spring依赖注入
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)
spring ioc容器初始化好bean的实例对象之后,会对该对象中的属性进行初始化,初始化的过程依然是由容器自动来完成,这个被称为是依赖注入(dependency injection缩写是DI)。spring里面常用的注入方式有两种,setter方法注入,构造方法注入。
还有一种方式是实现特定接口注入。由于这种方式采用侵入式编程,污染代码,所以已经不用了。
基于XML配置文件的依赖注入
setter方法注入
容器通过调用setter方法将对象注入,这种方式比较简单,所以使用的概率比较高。
<!--使用set方式进行依赖注入--> <bean id="UserService" class="com.shankai.service.UserServiceImpl"> <property name="userDao" ref="UserDaoId"/> name和set方法中UserDao对象引用名相同,创建其对象 </bean> <bean id="UserDaoId" class="com.shankai.dao.UserDaoImpl"/> 找到需要创建对象的类
构造注入
构造注入是容器通过构造方法将实例化的对象进行注入。
<!--使用构造方法进行依赖注入--> <bean id="UserService" class="com.shankai.service.UserServiceImpl"> <constructor-arg ref="UserDaoId" name="userDao"/> </bean> <bean id="UserDaoId" class="com.shankai.dao.UserDaoImpl"/>
基于注解的依赖注入
1、包扫描+组件标注注解。
@Component、@Repository、@Service、@Controller
<!--文件扫描器-->
<context:component-scan base-package="com.sk"/>
2、使用配置类。
@Configuration+@Bean注解
3、使用@import快速注入。
4、使用spring提供的FactoryBean
public class Student implements FactoryBean { @Override public Object getObject() throws Exception { return new Student(); } @Override public Class<?> getObjectType() { return Student.class; } }
Bean的生命周期(四种方法)
1、指定初始化和销毁方法。
bean:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Color { public Color() { System.out.println("color 创建...."); } public void init() { System.out.println("bean 初始化"); } public void destroy() { System.out.println("bean 销毁"); } }
配置类:
@Configuration public class MyConfig { @Bean( initMethod = "init", destroyMethod = "destroy" ) public Color color() { return new Color(); } }
测试方法:
@Test public void beanTest() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); System.out.println("容器创建..."); context.close(); }
结果:容器创建时新建bean赋值完成再初始化,容器关闭时销毁bean(单实例),多实例不会销毁bean。
color 创建....
bean 初始化
容器创建...
bean 销毁
2、让bean继承DisposableBean,InitializingBean
public class Color implements DisposableBean,InitializingBean{ public Color() { System.out.println("color 创建...."); } @Override public void destroy() throws Exception { System.out.println("bean 销毁!!!"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("bean 初始化!!!"); } }
3、使用@PostConstruct和@PreDestroy注解。
public class Color { public Color() { System.out.println("color 创建...."); } //对象创建并初始化完成之后调用 @PostConstruct public void init() { System.out.println("@PostConstruct..."); } //对象销毁之前调用 @PreDestroy public void destroy() { System.out.println("@PreDestroy..."); } }
4、使用bean的后置处理器 BeanPostProcessor
在bean创建之后 ,初始化之前调用before方法,初始化之后调用after方法。
public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
自动装配 :spring利用依赖注入,完成对IOC容器中各个组件的依赖关系赋值。
@Autowired:
1)、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。
2)、如果容器中该类型的组件有多个,则按照id进行装配。
2)、如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。