我对inversion of control( IoC
)在 Spring
中的工作方式感到有些困惑 .
Say I have a service class called UserServiceImpl that implements UserService interface.
怎么会 @Autowired
?
在我的 Controllers
中,我将如何 instantiate
这个服务的 instance
?
我会做以下吗?
UserService userService = new UserServiceImpl();
8 回答
Spring依赖注入可以帮助您从类中删除耦合 . 而不是像这样创建对象
您将在介绍DI后使用此功能
为实现此目的,您需要在ServiceConfiguration文件中创建服务的bean . 之后,您需要将该ServiceConfiguration类导入WebApplicationConfiguration类,以便您可以将此自动装配到Controller中 .
你可以在这里找到一个基于Java配置的POC example
首先,也是最重要的 - 所有Spring bean都是托管的 - 它们“活在”容器内,称为“应用程序上下文” .
其次,每个应用程序都有一个入口点 . Web应用程序有一个Servlet,JSF使用el-resolver等 . 此外,还有一个应用程序上下文被引导的地方和所有bean - 自动装配 . 在Web应用程序中,这可以是启动侦听器 .
通过将一个bean的实例放入另一个bean的实例中的所需字段来实现自动装配 . 这两个类都应该是bean,即它们应该被定义为存在于应用程序上下文中 .
什么是"living"在应用程序上下文中?这意味着上下文实例化对象,而不是您 . 即 - 你从不做
new UserServiceImpl()
- 容器找到每个注入点并在那里设置一个实例 .在您的控制器中,您只需拥有以下内容:
几点说明:
在
applicationContext.xml
中,您应启用<context:component-scan>
,以便扫描类以查找@Controller
,@Service
等注释 .Spring-MVC应用程序的入口点是DispatcherServlet,但它对您是隐藏的,因此应用程序上下文的直接交互和引导发生在场景后面 .
UserServiceImpl
也应定义为bean - 使用<bean id=".." class="..">
或使用@Service
注释 . 因为它将是UserService
的唯一实现者,所以它将被注入 .除了
@Autowired
注释之外,Spring还可以使用XML可配置的自动装配 . 在这种情况下,具有与现有bean匹配的名称或类型的所有字段将自动获取注入的bean . 事实上,这是自动装配的最初想法 - 在没有任何配置的情况下为字段注入依赖关系 . 也可以使用其他注释,如@Inject
,@Resource
.@Autowired
是Spring 2.5中引入的注释,它仅用于注入 .例如:
取决于您是否使用了注释路由或bean XML定义路由 .
假设您在
applicationContext.xml
中定义了bean:应用程序启动时会发生自动装配 . 所以,在
fooController
中,为了论证,想要使用UserServiceImpl
类,你需要注释如下:当它看到
@Autowired
时,Spring将查找与applicationContext中的属性匹配的类,并自动注入它 . 如果您有多个UserService bean,那么您必须确定应该使用哪一个 .如果您执行以下操作:
除非你自己设置,否则它不会接收@Autowired .
请记住,必须通过在 spring 配置文件中添加元素
<context:annotation-config/>
来启用@Autowired注释 . 这将注册AutowiredAnnotationBeanPostProcessor,它负责处理注释 .然后,您可以使用Field Injection方法自动装配您的服务 .
我从帖子Spring @autowired annotation找到了这个
@Autowired如何在内部工作?
前 -
.xml文件如果不使用@Autowired它看起来很相似
如果您正在使用@Autowired
.xml文件如果不使用@Autowired它看起来很相似
如果仍有疑问,请通过下面的现场演示
How does @Autowired work internally ?
控制反转的整个概念意味着您无需手工操作实例化对象并提供所有必需的依赖项 . 当您使用适当的注释(例如
@Service
)注释类时,Spring将自动为您实例化对象 . 如果您不熟悉注释,则也可以使用XML文件 . 但是,当您不想加载整个spring上下文时,在单元测试中手动实例化类(使用new
关键字)并不是一个坏主意 .您只需要使用注释注释您的服务类UserServiceImpl
Spring容器将在注册为服务时处理此类的生命周期 .
然后在您的控制器中,您可以自动连接(实例化)它并使用其功能 .