自动布线在春季如何工作?

我对控制反转()中的工作原理有点困惑。IoCSpring

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

这是怎么回事?@Autowired

在我的,我将如何获得这项服务?Controllersinstantiateinstance

我会做以下事情吗?

UserService userService = new UserServiceImpl();

答案 1

首先,也是最重要的 - 所有Spring bean都受到管理 - 它们“生活在”一个称为“应用程序上下文”的容器中。

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

通过将一个 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
  • Spring-MVC 应用程序的入口点是 DispatcherServlet,但它对您来说是隐藏的,因此应用程序上下文的直接交互和引导发生在幕后。
  • UserServiceImpl也应该被定义为bean - 使用或使用注释。由于它将是 的唯一实现者,因此它将被注入。<bean id=".." class="..">@ServiceUserService
  • 除了注释之外,Spring还可以使用XML可配置的自动布线。在这种情况下,所有具有与现有 Bean 匹配的名称或类型的字段都将自动注入 Bean。实际上,这就是自动布线的最初想法 - 在没有任何配置的情况下为字段注入依赖项。也可以使用其他注释,如 。@Autowired@Inject@Resource

答案 2

取决于您是需要批注路由还是 Bean XML 定义路由。

假设您在以下代码中定义了豆子:applicationContext.xml

<beans ...>

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

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

</beans>

自动布线在应用程序启动时发生。因此,在 中,为了参数而想要使用该类,您可以按如下方式对其进行注释:fooControllerUserServiceImpl

public class FooController {

    // You could also annotate the setUserService method instead of this
    @Autowired
    private UserService userService;

    // rest of class goes here
}

当它看到时,Spring 会查找与 中的属性匹配的类,并自动注入它。如果您有多个豆子,那么您必须限定它应该使用哪一个。@AutowiredapplicationContextUserService

如果执行以下操作:

UserService service = new UserServiceImpl();

除非您自己设置,否则它不会拾取。@Autowired


推荐