刚刚接触spring 最近一直不懂注入是什么,看到好多篇文章,现在总结一下spring的IOC
首先什么是IOC,学名叫控制反转,但是由于不好理解字面意思,后来又叫依赖注入。
依赖注入是什么呢,这个一看名字就知道了,需要依赖别人才能实现自己的需求,而在spring中,我们可以设置很多Bean实例,在java中我们不用自己创建对象就能自己获取自己的实例,当然默认情况下都是单例模式。是不是很神奇,那么我们就先看看都有几种实现这种功能的方法:
第一、setter 方法
applicationContext.xml配置
<bean id="testService" class="org.lc.controller.TestController">
<property name="testService" ref="testServiceImpl"></property>
</bean>
<bean id="testServiceImpl" class="org.lc.service.impl.TestServiceImpl"/>
TestController配置
(ps:今天运行了一上午,都发现spring的依赖注入一直运行不出来,一直提示我请求过多,我也是在网上看了各路大神的问题解决方案,发现根本没找到我想要的答案。最后在自己的琢磨下,发现要想注入到Controller层必须在spring mvc注入,而且注入的类不能被扫描即不能写注解@Controller(因为我写了扫描)。这样终于运行成功了。在这个过程中也学到了一些spring的原理:
1、在spring-MVC.xml定义的Bean可以直接在spring.xml(applicationContext.xml)中引用,而反过来不行。
2、引入配置文件只能在一个地方写,我见网上是这样写的,在一个xml配置这样一个配置文件,然后再引入其它配置文件。这也算是spring让我们逼我们干的吧,结构逻辑比较清晰,不会写的太乱。
好了,废话不多说,把上面的改了,改到spring-mvc.xml不然没法加载请求(好像是加载请求还要依赖于Bean),会报404,依赖注入从新开始)
第一 、setter方法
spring-mvc.xml配置
<bean id="testService" class="org.lc.controller.TestController">
<property name="testService" ref="testServiceImpl"></property>
</bean>
<bean id="testServiceImpl" class="org.lc.service.impl.TestServiceImpl"/>
TestController配置
@RequestMapping("/test")
public class TestController {
private TestService testService;
public void setTestService(TestService testService){
this.testService=testService;
}
}
第二、构造方法
spring-mvc.xml配置
<bean id="testService" class="org.lc.controller.TestController">
<constructor-arg index="0" ref="testServiceImpl"/>
</bean>
<bean id="testServiceImpl" class="org.lc.service.impl.TestServiceImpl"/>
TestController配置
@RequestMapping("/test")
public class TestController {
private TestService testService;
TestController(TestService testService){
this.testService=testService;
}
...
}
第三、工厂方法(仍需要setter方法,但xml又配置不同)
新建一个工厂类
public class TestBeanFactory {
//静态工厂方法
public static TestService getStaticTestServiceImpl(){
return new TestServiceImpl();
}
//实例工厂方法
public TestService getTestServiceImpl(){
return new TestServiceImpl();
}
}
TestController.java配置
@RequestMapping("/test")
public class TestController {
private TestService testService;
public void setTestService(TestService testService){
this.testService=testService;
}
}
主要看spring-mvc.xml文件与setter方法的不同
<bean id="testService" class="org.lc.controller.TestController">
<property name="testService" ref="beanFactory"></property>
</bean>
<!-- 静态工厂 -->
<bean id="beanFactory" class="org.lc.util.TestBeanFactory" factory-method="getStaticTestServiceImpl"/>
<!-- 或者用实例工厂 -->
<bean id="beanFactory" class="org.lc.util.TestBeanFactory" factory-method="getTestServiceImpl"/>
注入的三种方式基本上讲完了,但是由于上面的现在都没怎么用过,理解不对的还请大神多多指教~~
下面讲一下扫描:也算是一种注入的方式:通过注解的方式注入。
<context:annotation-config/> <!-- 开启注解处理器//可以不写,因为扫描会自动开启注解。建议写上-->
<!-- base-package 会扫描这个包下面的所有注解:包括@Component,@Service,@Controller,@Repository等,而use-default-filters则是判断是否进行全部扫描 -->
<context:component-scan base-package="org.lc.controller" use-default-filters="false">
<!-- 他下面有两个子标签,一个是include-filter:扫描某个注解;exclude-filter:不扫描某个注解 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
这样扫描比单独注入要省很多力气,全都交给spring这个管理器给我们干活,我们只要站好队等着它给我们喂吃的就行了。
努力就有一切,快乐生活,快乐写最美一切。还请多多指教。