首页 文章

自动装配如何在Spring工作?

提问于
浏览
425

我对inversion of controlIoC )在 Spring 中的工作方式感到有些困惑 .

Say I have a service class called UserServiceImpl that implements UserService interface.

怎么会 @Autowired

在我的 Controllers 中,我将如何 instantiate 这个服务的 instance

我会做以下吗?

UserService userService = new UserServiceImpl();

8 回答

  • 9

    Spring依赖注入可以帮助您从类中删除耦合 . 而不是像这样创建对象

    UserService userService = new UserServiceImpl();
    

    您将在介绍DI后使用此功能

    @Autowired
    private UserService userService;
    

    为实现此目的,您需要在ServiceConfiguration文件中创建服务的bean . 之后,您需要将该ServiceConfiguration类导入WebApplicationConfiguration类,以便您可以将此自动装配到Controller中 .

    public class AccController {
    
        @Autowired
        private UserService userService;
    }
    

    你可以在这里找到一个基于Java配置的POC example

  • 1

    首先,也是最重要的 - 所有Spring bean都是托管的 - 它们“活在”容器内,称为“应用程序上下文” .

    其次,每个应用程序都有一个入口点 . Web应用程序有一个Servlet,JSF使用el-resolver等 . 此外,还有一个应用程序上下文被引导的地方和所有bean - 自动装配 . 在Web应用程序中,这可以是启动侦听器 .

    通过将一个bean的实例放入另一个bean的实例中的所需字段来实现自动装配 . 这两个类都应该是bean,即它们应该被定义为存在于应用程序上下文中 .

    什么是"living"在应用程序上下文中?这意味着上下文实例化对象,而不是您 . 即 - 你从不做 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 等注释 .

    • Spring-MVC应用程序的入口点是DispatcherServlet,但它对您是隐藏的,因此应用程序上下文的直接交互和引导发生在场景后面 .

    • UserServiceImpl 也应定义为bean - 使用 <bean id=".." class=".."> 或使用 @Service 注释 . 因为它将是 UserService 的唯一实现者,所以它将被注入 .

    • 除了 @Autowired 注释之外,Spring还可以使用XML可配置的自动装配 . 在这种情况下,具有与现有bean匹配的名称或类型的所有字段将自动获取注入的bean . 事实上,这是自动装配的最初想法 - 在没有任何配置的情况下为字段注入依赖关系 . 也可以使用其他注释,如 @Inject@Resource .

  • 620

    @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(););
        }
    }
    
  • 18

    取决于您是否使用了注释路由或bean XML定义路由 .

    假设您在 applicationContext.xml 中定义了bean:

    <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,那么您必须确定应该使用哪一个 .

    如果您执行以下操作:

    UserService service = new UserServiceImpl();
    

    除非你自己设置,否则它不会接收@Autowired .

  • 61

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

    然后,您可以使用Field Injection方法自动装配您的服务 .

    public class YourController{
    
     @Autowired
     private UserService userService; 
    
    }
    

    我从帖子Spring @autowired annotation找到了这个

  • 4

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

    如果仍有疑问,请通过下面的现场演示

    How does @Autowired work internally ?

  • 0

    控制反转的整个概念意味着您无需手工操作实例化对象并提供所有必需的依赖项 . 当您使用适当的注释(例如 @Service )注释类时,Spring将自动为您实例化对象 . 如果您不熟悉注释,则也可以使用XML文件 . 但是,当您不想加载整个spring上下文时,在单元测试中手动实例化类(使用 new 关键字)并不是一个坏主意 .

  • 0

    您只需要使用注释注释您的服务类UserServiceImpl

    @Service("userService")
    

    Spring容器将在注册为服务时处理此类的生命周期 .

    然后在您的控制器中,您可以自动连接(实例化)它并使用其功能 .

    @Autowired
    UserService userService;
    

相关问题