답변:
첫째, 가장 중요한-모든 스프링 빈은 관리되고 있으며 "응용 프로그램 컨텍스트"라는 컨테이너 안에 "살아"있습니다.
둘째, 각 응용 프로그램에는 해당 컨텍스트에 대한 진입 점이 있습니다. 웹 응용 프로그램에는 서블릿이 있고 JSF 는 el-resolver 등을 사용합니다. 또한 응용 프로그램 컨텍스트가 부트 스트랩되고 모든 Bean이 자동 연결되는 곳이 있습니다. 웹 애플리케이션에서 이것은 시작 리스너 일 수 있습니다.
자동 배선은 한 Bean의 인스턴스를 다른 Bean 인스턴스의 원하는 필드에 배치하여 발생합니다. 두 클래스는 모두 Bean이어야합니다. 즉, 응용 프로그램 컨텍스트에 맞게 정의되어야합니다.
응용 문맥에서 "생존"이란 무엇입니까? 이는 컨텍스트가 사용자가 아닌 객체를 인스턴스화 한다는 것을 의미 합니다. 즉, 절대 만들지 않습니다 new UserServiceImpl()
. 컨테이너는 각 주입 지점을 찾아 인스턴스를 설정합니다.
컨트롤러에는 다음이 있습니다.
@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {
// Tells the application context to inject an instance of UserService here
@Autowired
private UserService userService;
@RequestMapping("/login")
public void login(@RequestParam("username") String username,
@RequestParam("password") String password) {
// The UserServiceImpl is already injected and you can use it
userService.login(username, password);
}
}
몇 가지 참고 사항 :
applicationContext.xml
당신은 활성화해야 <context:component-scan>
수업이 검사되도록 @Controller
, @Service
등 주석.UserServiceImpl
주석을 사용 <bean id=".." class="..">
하거나 사용 하여 Bean으로 정의해야합니다 @Service
. 의 유일한 구현 자이므로 UserService
주입됩니다.@Autowired
주석 외에도 Spring은 XML 구성 가능한 자동 배선을 사용할 수 있습니다. 이 경우 기존 Bean과 일치하는 이름 또는 유형을 가진 모든 필드는 자동으로 Bean을 가져옵니다. 사실, 그것은 자동 배선의 초기 아이디어였습니다. 필드를 구성하지 않고 의존성으로 필드를 주입하십시오. 다른 주석처럼 @Inject
, @Resource
또한 사용할 수 있습니다.주석 경로를 원하는지 아니면 Bean XML 정의 경로를 원하는지에 따라 다릅니다.
에 콩을 정의했다고 가정 해보십시오 applicationContext.xml
.
<beans ...>
<bean id="userService" class="com.foo.UserServiceImpl"/>
<bean id="fooController" class="com.foo.FooController"/>
</beans>
자동 배선은 응용 프로그램이 시작될 때 발생합니다. 따라서 fooController
인수에 대해 UserServiceImpl
클래스 를 사용하려는 에서는 다음과 같이 주석을 달 것입니다.
public class FooController {
// You could also annotate the setUserService method instead of this
@Autowired
private UserService userService;
// rest of class goes here
}
이 표시되면 @Autowired
Spring 은의 속성과 일치하는 클래스를 찾아 applicationContext
자동으로 주입합니다. 하나 이상의 UserService
Bean 이있는 경우 사용할 Bean을 규정해야합니다.
다음을 수행하는 경우 :
UserService service = new UserServiceImpl();
@Autowired
직접 설정하지 않으면 픽업하지 않습니다 .
bean id
에가 applicationContext.xml
. 타입으로 userService
변수 를 정의해야 합니다 UserService
. 그래서 왜 xml
파일에 항목을 작성 하십시오.
@Autowired
Spring 2.5에서 소개 된 주석으로, 주입에만 사용됩니다.
예를 들면 다음과 같습니다.
class A {
private int id;
// With setter and getter method
}
class B {
private String name;
@Autowired // Here we are injecting instance of Class A into class B so that you can use 'a' for accessing A's instance variables and methods.
A a;
// With setter and getter method
public void showDetail() {
System.out.println("Value of id form A class" + a.getId(););
}
}
@Autowired
" B
클래스의 클래스에 있는 모든 함수 (방법) 및 변수를 사용할 수 있습니다"는 의미는 아닙니다 A
. 그것이 무엇 것은 인스턴스 제공 A
의 인스턴스로를 B
, 그래서 당신은 할 수 a.getId()
에서 B
.
@Autowired
내부적으로 어떻게 작동합니까?
예:
class EnglishGreeting {
private Greeting greeting;
//setter and getter
}
class Greeting {
private String message;
//setter and getter
}
.xml 파일을 사용하지 않으면 비슷하게 보입니다 @Autowired
.
<bean id="englishGreeting" class="com.bean.EnglishGreeting">
<property name="greeting" ref="greeting"/>
</bean>
<bean id="greeting" class="com.bean.Greeting">
<property name="message" value="Hello World"/>
</bean>
당신이 사용하는 @Autowired
경우 :
class EnglishGreeting {
@Autowired //so automatically based on the name it will identify the bean and inject.
private Greeting greeting;
//setter and getter
}
.xml 파일을 사용하지 않으면 비슷하게 보입니다 @Autowired
.
<bean id="englishGreeting" class="com.bean.EnglishGreeting"></bean>
<bean id="greeting" class="com.bean.Greeting">
<property name="message" value="Hello World"/>
</bean>
여전히 의심이 있다면 라이브 데모 아래를 살펴보십시오.
스프링 의존성 주입은 클래스에서 커플 링을 제거하는 데 도움이됩니다. 다음과 같은 객체를 만드는 대신 :
UserService userService = new UserServiceImpl();
DI를 소개 한 후에 이것을 사용할 것입니다 :
@Autowired
private UserService userService;
이를 위해서는 ServiceConfiguration
파일에 서비스 Bean을 작성해야 합니다. 그런 다음 해당 ServiceConfiguration
클래스를 클래스 로 가져 와서 WebApplicationConfiguration
다음과 같이 해당 Bean을 Controller에 자동 와이어 링 할 수 있습니다.
public class AccController {
@Autowired
private UserService userService;
}
현재 자바 구성을 기반으로 POC 찾을 수 있습니다 예를 들어 .
표준 방식 :
@RestController
public class Main {
UserService userService;
public Main(){
userService = new UserServiceImpl();
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
사용자 서비스 인터페이스 :
public interface UserService {
String print(String text);
}
UserServiceImpl 클래스 :
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
산출: Example test UserServiceImpl
이것은 꽉 결합 된 클래스, 나쁜 디자인 예제의 좋은 예이며 테스트에 문제가있을 것입니다 (PowerMockito도 나쁩니다).
이제 느슨한 결합의 좋은 예인 SpringBoot 의존성 주입을 살펴 보자.
인터페이스는 동일하게 유지됩니다.
메인 클래스 :
@RestController
public class Main {
UserService userService;
@Autowired
public Main(UserService userService){
this.userService = userService;
}
@GetMapping("/")
public String index(){
return userService.print("Example test");
}
}
ServiceUserImpl 클래스 :
@Component
public class UserServiceImpl implements UserService {
@Override
public String print(String text) {
return text + " UserServiceImpl";
}
}
산출: Example test UserServiceImpl
이제 테스트를 작성하기 쉽습니다.
@RunWith(MockitoJUnitRunner.class)
public class MainTest {
@Mock
UserService userService;
@Test
public void indexTest() {
when(userService.print("Example test")).thenReturn("Example test UserServiceImpl");
String result = new Main(userService).index();
assertEquals(result, "Example test UserServiceImpl");
}
}
내가 보여 @Autowired
생성자에 주석을하지만, 그것은 또한 세터 또는 필드에서 사용할 수 있습니다.
스프링 구성 파일에 @Autowired
요소 <context:annotation-config/>
를 추가 하여 주석을 활성화해야 합니다. AutowiredAnnotationBeanPostProcessor
주석 처리를 담당하는 등록합니다 .
그리고 필드 주입 방법을 사용하여 서비스를 자동 와이어 링 할 수 있습니다.
public class YourController{
@Autowired
private UserService userService;
}
나는 Spring @ autowired 주석 에서 이것을 발견했다.
을 사용하여 인스턴스를 만들 수있는 방법은 3 가지가 있습니다 @Autowired
.
1. @Autowired
속성
주석은 속성에 직접 사용될 수 있으므로 게터와 세터가 필요하지 않습니다.
@Component("userService")
public class UserService {
public String getName() {
return "service name";
}
}
@Component
public class UserController {
@Autowired
UserService userService
}
위 예제에서 Spring 은 생성 userService
될 때 찾아서 주입 UserController
합니다.
2. @Autowired
세터에서
@Autowired
주석은 setter 메소드에서 사용할 수 있습니다. 아래 예제에서 주석이 setter 메소드에서 사용될 때 setter 메소드는 userService
when UserController
가 작성된 인스턴스와 함께 호출됩니다 .
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
3. @Autowired
생성자
@Autowired
주석은 또한 생성자에서 사용할 수 있습니다. 아래 예제에서 생성자가 주석을 사용하는 경우 생성시 인스턴스의 인스턴스가 생성자에 userService
대한 인수로 삽입됩니다 UserController
.
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService= userService;
}
}
간단히 말해서 자동 배선, 자동으로 링크 연결은 이제 누가이 작업을 수행하고 어떤 종류의 배선을 수행해야하는지에 대한 질문을받습니다. 답은 : 컨테이너가이를 수행하고 2 차 유형의 배선이 지원되므로 기본 요소를 수동으로 수행해야합니다.
질문 : 컨테이너는 어떤 유형의 배선을 알고 있습니까?
답변 : 우리는 그것을 byType, byName, 생성자로 정의합니다.
질문 : 자동 배선 유형을 정의하지 않는 방법이 있습니까?
답 : 예. @Autowired라는 주석 하나만 사용하면됩니다.
질문 : 그러나 시스템이 어떻게 알 수 있습니까?이 유형의 보조 데이터를 선택해야합니까?
답 : 컨테이너에서 스스로 객체를 생성 할 수 있도록 spring.xml 파일에 데이터를 제공하거나 클래스에 sterotype 주석을 사용하십시오.