Bean的作用范围
通过注解配置的Bean和通过<bean>
配置的Bean一样,默认的作用范围都是singleton。
Spring为注解配置提供了一个@Scope注解,可以通过它显示指定Bean的作用范围。
实例
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster
package com.xgj.ioc.configuration.lifeCycle; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Scope("prototype") @Component public class Teacher { private Student student; /** * * * @Title:Teacher * * @Description:构造函数 */ public Teacher() { super(); System.out.println("Teacher is initing...."); } @Autowired public void setStudent(Student student) { this.student = student; } }
package com.xgj.ioc.configuration.lifeCycle; import org.springframework.stereotype.Component; @Component public class Student { public Student() { super(); System.out.println("Student is initing...."); } }
配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- (1)声明Context命名空间以及Schema文件 (2)扫描类包以及应用注解定义的bean --> <context:component-scan base-package="com.xgj.ioc.configuration.lifeCycle"/> </beans>
测试类
package com.xgj.ioc.configuration.lifeCycle; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ScopeTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/xgj/ioc/configuration/lifeCycle/beanLifeCycle.xml"); System.out.println("isPrototype:" + ctx.isPrototype("teacher")); System.out.println("isSingleton:" + ctx.isSingleton("teacher")); } }
运行结果:
Bean的生命周期方法
@Scope注解通过入参指定Bean的作用范围。 在使用<bean>进行配置可以通过init-method和destory属性指定Bean的初始化及容器销毁前执行的方法。
Spring从2.5开始支持JSR-250中定义的@PostConstruct和PreDestory注解。 在Spring中这两个注解相当于init-method和destroy-method属性的功能。 不过在使用注解时,可以在一个bean 中定义多个@PostConstruct和@PreDestory方法。
实例
我们取消掉Teacher类的 @Scope(“prototype”) 注解 (因为对于singleton的Bean,容器管理,prototype由调用者管理,Spring不管理) ,增加 @PostConstruct 和PreDestory。
改造如下
package com.xgj.ioc.configuration.lifeCycle; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; //@Scope("prototype") @Component public class Teacher { private Student student; /** * * * @Title:Teacher * * @Description:构造函数 */ public Teacher() { super(); System.out.println("Teacher is initing...."); } @Autowired public void setStudent(Student student) { this.student = student; } @PostConstruct public void init1() { System.out.println("init 1"); } @PostConstruct public void init2() { System.out.println("init 2"); } @PreDestroy public void destory1() { System.out.println("destory 1"); } @PreDestroy public void destory2() { System.out.println("destory 2"); } }
测试类
package com.xgj.ioc.configuration.lifeCycle; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class ScopeTest { public static void main(String[] args) { // 启动容器 ApplicationContext ctx = new ClassPathXmlApplicationContext( "classpath:com/xgj/ioc/configuration/lifeCycle/beanLifeCycle.xml"); System.out.println("isPrototype:" + ctx.isPrototype("teacher")); System.out.println("isSingleton:" + ctx.isSingleton("teacher")); // 关闭容器,对于singleton的Bean,容器管理,prototype由调用者管理,Spring不管理 ((ClassPathXmlApplicationContext) ctx).destroy(); } }
运行结果:
由此可以看出,Spring先调用类的构造函数实例化Bean,然后在执行@Autowired进行自动注入,然后分别执行标注了@PostConstruct的方法,然后在容器关闭时,分别执行了标注@PreDestroy的方法。