spring bean注入方式
构造器注入
<!--构造器注入-->
<bean id="user" class="com.sean.spring.User">
<constructor-arg index="0" value="德莱文"/>
<constructor-arg index="1" value="18"/>
</bean>
setter注入
<!--setter注入-->
<bean id="user" class="com.sean.spring.User">
<property name="name" value="无敌"></property>
<property name="age" value="18"></property>
</bean>
如果我们一个类中多个参数,那么我们要赋值岂不是通过以上两种方法要写很多,除了通过xml注入,还可以通过注解的方式注入注入。
context:annotation-config ,用于激活那些已经在spring容器里注册过的bean
<context:annotation-config></context:annotation-config>
<bean id="user" class="com.sean.spring.User"/>
然后在类中需要注入值的属性上添加@Autowired,如果需要设置,可通过 @Value直接给值
@Autowired
@Value("无敌")
public void setName(String name) {
this.name = name;
}
@Autowired
@Value("25")
public void setAge(Integer age) {
this.age = age;
}
当然项目中有很多类,通过这种方式,岂不是也要配置很多的bean,别怕,Spring提供了扫描包的方式。
context:component-scan自动将带有@component,@service,@Repository等注解的对象注册到spring容器中的功能。
<context:component-scan base-package="com.sean.spring" />
只需在类中添加@Component
@Component
public class User{
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
@Autowired
@Value("无敌")
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUser(){
String user = "我的名字是"+ name+"我今年" + age+"岁";
return user;
}
}
测试后输出:
我们将applicationContext.xml配置文件作如下修改:
关于spring配置注解context:annotation-config
和context:component-scan
区别,网上很多博客都有讲解
Spring bean 的生命周期
- 如果Bean实现了
BeanNameAware
的setBeanName
方法,那么它就会调用这个方法。 - 如果Bean实现了
BeanFactoryAware
的setBeanFactory
方法,那么它就会调用这个方法。 - 如果Bean实现了
ApplicationContextAware
的setApplicationContext
方法,且Spring IoC容器也必须是一个ApplicationContext
接口的实现类,那么才会调用这个接口,否则不调用 - 如果Bean实现了
BeanPostProcessor
的postProcessBeforeInitialization
方法,那么它就会调用这个方法。 - 如果Bean实现了
InitializingBean
的afterPropertiesSet
方法,那么它就会调用这个方法。 - 如果Bean自定义了初始化方法,那么它就会调用这个方法。
- 如果Bean实现了
BeanPostProcessor
的postProcessAfterInitialization
方法,完成这些调用,这时候Bean就完成了初始化 - 当服务器关闭,调用对应额方法完成Bean的销毁
- 如果Bean实现了
DisposableBean
的destroy
方法,那么它就会调用这个方法。 - 如果自定义销毁对象,那么就会调用它。
下边我们来测试一下,先测试一下BeanPostProcessor
接口。
我们下一个实现类BeanPostProcessorImpl
public class BeanPostProcessorImpl implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】"+beanName + "开始实例化");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】"+beanName + "实例化完成");
return bean;
}
}
这样一个BeanPostProcessor
就被我们用代码实现了,它会处理Spring IoC容器所有的Bean
测试生命周期
public class User implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void init(){
System.out.println("【"+this.getClass().getSimpleName()+"】" + "执行自定义初始化方法");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】" + "setBeanFactory");
}
public String getUser(){
String user = "我的名字是"+ name+"我今年" + age+"岁";
return user;
}
public void setBeanName(String s) {
System.out.println("【"+this.getClass().getSimpleName()+"】"+ "setBeanName");
}
public void myDestroy() throws Exception {
System.out.println("【"+this.getClass().getSimpleName()+"】"+ "自定义销毁");
}
public void destroy() throws Exception {
System.out.println("【"+this.getClass().getSimpleName()+"】"+ "destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("【"+this.getClass().getSimpleName()+"】" + "afterPropertiesSet");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】"+ "setApplicationContext");
}
}
这个类实现了所有生命周期所能实现的方法,以便于观察生命周期的过程,其中init
方法是自定义初始化方法,myDestroy
方法是自定义销毁方法。
我们修改配置文件spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanPostProcessor" class="com.sean.spring.BeanPostProcessorImpl"/>
<!--setter注入-->
<bean id="user" class="com.sean.spring.User" init-method="init" destroy-method="myDestroy">
<property name="name" value="无敌"></property>
<property name="age" value="18"></property>
</bean>
</beans>
写一个测试类,看一下结果
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring/spring-config.xml");
User user = context.getBean(User.class);
logger.debug(user.getUser());
((ClassPathXmlApplicationContext) context).close();
}
打印日志: