自动assembly在spring如何工作?

对于Spring 的控制反转 ( IoC )是如何工作的,我有点困惑。

假设我有一个名为UserServiceImpl的服务类实现了UserService接口。

这将是@Autowired

在我的Controllers操作中,我将如何instantiate此服务的一个instance

我会做下面的事吗?

 UserService userService = new UserServiceImpl(); 

首先,也是最重要的 – 所有的Spring bean都被pipe理 – 它们“活在”一个容器内,称为“应用程序上下文”。

其次,每个应用程序都有一个入口点。 Web应用程序有一个Servlet, JSF使用elparsing器等等。另外,还有一个地方是应用程序上下文被引导,所有的bean都是自动assembly的。 在Web应用程序中,这可以是一个启动监听器。

自动assembly通过将一个bean的实例放入另一个bean实例的所需字段中来实现。 这两个类都应该是bean,也就是说,它们应该被定义为生存在应用程序上下文中。

什么是应用程序环境中的“生活”? 这意味着上下文实例化对象,而不是你。 也就是说,你永远不会创buildnew UserServiceImpl() – 容器find每个注入点并在那里设置一个实例。

在你的控制器中,你只需要:

 @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>以便<context:component-scan>类的@Controller@Service @Controller等注释。
  • Spring-MVC应用程序的入口点是DispatcherServlet,但它对您来说是隐藏的,因此应用程序上下文的直接交互和引导发生在场景后面。
  • UserServiceImpl也应该被定义为bean – 使用<bean id=".." class="..">或使用@Service注释。 由于它将是UserService的唯一实现者,因此将被注入。
  • 除了@Autowired注解,Spring可以使用XMLconfiguration的自动assembly。 在这种情况下,具有与现有bean相匹配的名称或types的所有字段将自动获取注入的bean。 实际上,这是自动assembly的最初想法 – 在没有任何configuration的情况下使用依赖关系注入字段。 其他注释(如@ @Inject@Resource也可以使用。

取决于你是去注释path还是bean的XML定义路线。

假定你的applicationContext.xml定义了bean:

 <beans ...> <bean id="userService" class="com.foo.UserServiceImpl"/> <bean id="fooController" class="com.foo.FooController"/> </beans> 

自动assembly发生在应用程序启动时。 所以,在fooController ,为了参数的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中的属性的类,并自动注入它。 如果你有超过1个UserService bean,那么你将不得不限定它应该使用哪一个。

如果您执行以下操作:

 UserService service = new UserServiceImpl(); 

除非你自己设置@Autowired,否则它将不会起作用。

@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; private int roll; // With setter and getter method public void showDetail() { System.out.println("Value of id form A class" + a.getId();); } } 

@Autowired

  • 将构造函数,字段,setter方法或configuration方法标记为由Spring的dependency injection工具自动assembly。

  • 任何给定的bean类只有一个构造函数(max)可以携带这个注解,指示构造函数在用作Spring bean时自动assembly。 这样的构造不必公开。

  • 在调用任何configuration方法之前,在构buildbean之后立即注入字段。 这样的configuration字段不必公开。

  • configuration方法可以有任意的名字和任意数量的参数; 每个参数都将在Spring容器中使用匹配的bean进行自动assembly。 Bean属性setter方法实际上只是这种通用configuration方法的特例。 这种configuration方法不必公开。

  • 在多参数方法的情况下,“required”参数适用于所有参数。

  • 在Collection或Map依赖types的情况下,容器将自动装载符合声明值types的所有bean。 在Map的情况下,键必须声明为Stringtypes,并将parsing为相应的bean名称。

@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> 

如果仍然有一些疑问,然后通过下面的现场演示

@Autowired如何在内部工作?

你只需要用注解来注释你的服务类UserServiceImpl

 @Service("userService") 

Spring容器将注意到这个类的生命周期,因为它注册为服务。

然后在你的控制器中,你可以自动连线(实例化)并使用它的function。

 @Autowired UserService userService; 

Springdependency injection可以帮助你从类中移除耦合。 而不是像这样创build对象

 UserService userService = new UserServiceImpl(); 

介绍DI之后,您将使用这个

 @Autowired private UserService userService; 

为了达到这个目的,你需要在你的ServiceConfiguration文件中创build一个服务的bean。 之后,您需要将该ServiceConfiguration类导入到您的WebApplicationConfiguration类中,以便您可以像这样将该Autowire bean插入到您的Controller中。

 public class AccController { @Autowired private UserService userService; } 

你可以在这里find一个基于javaconfiguration的POC 例子

控制反转的整个概念意味着你不需要手动实例化对象,并提供所有必要的依赖关系。 当你使用适当的注解来注释类时(例如@Service ),Spring会自动为你实例化对象。 如果您不熟悉注释,则也可以使用XML文件。 但是,当您不想加载整个spring上下文时,在unit testing中手动实例化类(使用new关键字)并不是一个坏主意。

请记住,您必须通过在springconfiguration文件中添加元素<context:annotation-config/>来启用@Autowired注释。 这将注册AutowiredAnnotationBeanPostProcessor,它负责注释的处理。

然后,您可以使用字段注入方法自动装载您的服务。

 public class YourController{ @Autowired private UserService userService; } 

我从Spring的@autowired注释中find了这个