Spring实现IOC的思路是提供一些配置信息用来描述类之间的依赖关系,然后由容器去解析这些配置信息,继而维护好对象之间的依赖关系,前提是对象之间的依赖关系必须在类中定义好,比如A.class中有一个B.class的属性,那么我们可以理解为A依赖了B。既然我们在类中已经定义了他们之间的依赖关系那么为什么还需要在配置文件中去描述和定义呢?
Spring实现IOC的思路大致可以拆分成3点:
(1)应用程序中提供类,提供依赖关系(属性或者构造方法)
(2)把需要交给容器管理的对象通过配置信息告诉容器(xml、annotation,javaconfig)
(3)把各个类之间的依赖关系通过配置信息告诉容器
Spring的注入编码风格有三种,并且三种可以混合使用:
(1)schemal-based (实现方式:XML)
(2)annotation-based (实现方式:annotation注解)
(3)java-based (实现方式:configuration注解)
1. schemal-based(XML)注入的两种方法:
1.1 构造方法注入
定义有参数的构造方法:
public class ThingThree { public ThingThree(ThingOne thingOne, ThingTwo thingTwo){ // ... } }
XML定义注入:
<beans> <bean id="thingOne" class="com.xxx.ThingOne"/> <bean id="thingTwo" class="com.xxx.ThingTwo"/> <bean id="thingThree" class="com.xxx.ThingThree"> <constructor-arg ref="thingOne"/> <constructor-arg ref="thingTwo"/> </bean> </beans>
1.2 setter方法注入
定义Setter方法:
public class BeanOne { private BeanTwo beanTwo; public void setBeanTwo(BeanTwo beanTwo){ this.beanTwo = beanTwo; } }
XM定义注入:
<beans> <bean id="beanOne" class="com.xxx.BeanOne"/> <bean id="thingTwo" class="com.xxx.ThingTwo"> <property name="beanOne" ref="beanOne"/> <bean> </beans>
2. annotation-based (annotation注解)
bean使用的注解包括:@Component、@Repository、@Service、@Controller、@RestController
需要注入的类使用注解:@Autowired
XML配置扫描路径:
<!-- 开启扫描功能,这个配置是Spring3.0版本才需要用 --> <context:annotation-config></context:annotation-config> <!-- 设置扫描路径、开启扫描,Spring4.0版本之后只用这一个就够了 --> <context:component-scan base-package="com.xxx"/>
3. java-based(configuration注解)
在声明bean对象上使用注解:@Configuration
需要在bean类声明读取配置文件可以使用:@ImportResource("classpath:spring.xml")
bean上面设置组件扫描路径:@ComponentScan(basePackages = {"com.dxh.finance"})
自动装配
上面说过,IOC的注入有两个地方需要提供依赖关系,一是类的定义中,二是在spring的配置中需要去描述。自动装配则把第二个取消了,即我们仅仅需要在类中提供依赖,继而把对象交给容器管理即可完成注入。在实际开发中,描述类之间的依赖关系通常是大篇幅的,如果使用自动装配则省去了很多配置,并且如果对象的依赖发生更新我们可以不需要去更新配置,但是也带来了一定的缺点。
说白了就是只需要声明bean,至于对象间的相互引用关系由Spring自己搞定。。
使用方式:no(不启用),byName(根据名称),byType(根据类型),constructor(构造方法)
<beans .... default-autowire="byType"> </beans>
自动装配的优点参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-autowire
缺点参考文档:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-autowired-exceptions
spring懒加载
在Spring配置文件里增加如下语句,表示Spring并不是在在项目启动时全部注入,而是在使用时才会注入,默认false
<beans .....
default-lazy-init="true"> </beans>
SpringBean的作用域
singleton:单例
prototype:标准,每次都是新的对象
request:限定每个Http请求都是新的对象
session:将单个bean定义的范围限定为HTTP会话的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。
applicaiton:将单个bean定义的范围限定为ServletContext的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。
websocket:将单个bean定义的范围限定为WebSocket的生命周期。仅在可感知web的Spring ApplicationContext上下文中有效。