1.作用域分类
1.singleton(单例):某个类型的对象始终只有一个 例如飞翔小鸟中的天空
不要说单例模式!!!!!!
2.prototype(原型):某个类型的对象不唯一
默认情况下是单例的,任何时候调用getBean方法获得的对象都是同一个实例
测试:
@Test/*测试组件扫描*/
public void demoBean(){
DemoBean demoBean= a.getBean("demoBean",DemoBean.class);
DemoBean demoBean2= a.getBean("demoBean",DemoBean.class);
System.out.println(demoBean);
System.out.println(demoBean==demoBean2);
}
得到结果true
那么如何设置原型作用域??
方法是在pojo类上添加注解@Scope("prototype")
实现代码:
package cn.tedu.demo;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.io.Serializable;
@Component
@Scope("prototype")
public class DemoBean implements Serializable {
@Override
public String toString() {
return "DemoUser";
}
}
此时比较两个对象结果为false,说明生成了不同的对象
2.对象生命周期管理
BeanFactoryPostProcessor
package cn.tedu.demo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Component
public class MyBeanFactroyProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory
(ConfigurableListableBeanFactory configurableListableBeanFactory)
throws BeansException {
System.out.println("加载了Bean的定义");
/*列出当前spring存储的所有Bean名称*/
String[] names=configurableListableBeanFactory.getBeanDefinitionNames();
for(String name:names){
System.out.println(name);
}
}
}
package cn.tedu.context;
import cn.tedu.demo.MoonCake;
import cn.tedu.demo.MoonCakeFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FactoryBeanConfig {
@Bean
/*spring会自动调用getObject() 自动创建MookCake对象 Spring存储的对象是MoonCake类型*/
public MoonCakeFactory moonCake(){
return new MoonCakeFactory();
}
}
@Test
public void testBFPP(){
MyBeanFactroyProcessor myBeanFactroyProcessor=ctx.getBean(MyBeanFactroyProcessor.class);
System.out.println(myBeanFactroyProcessor);
}
BFPP BeanFactoryPostProcessor
BPP BeanPostProcessor Bean创建以后执行 Bean后期处理
生命周期:对象从创建到使用到销毁的过程,SpringIOC提供了对象生命周期的管理功能 执行了@PostConstruct
使用到了BeanPostProcessor接口
方式一:使用@Component注解管理Bean组件时
利用注解@PostConstruct(创建对象以后执行),@PreDestroy(容器关闭销毁对象时候执行)
测试步骤:
1.导入javax.annotation-api坐标
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
2.创建Bean组件
package cn.tedu.demo;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.PrintWriter;
@Component
public class FileLogger {
public PrintWriter out;
@PostConstruct
public void open() throws Exception {
out=new PrintWriter("Demo.txt");
System.out.println("打开文件Demo.txt");
}
@PreDestroy
public void close() throws Exception {
out.close();
System.out.println("关闭文件Demo.txt");
}
}
3.测试
@Test
public void testPostContruct(){
FileLogger fileLogger = a.getBean("fileLogger", FileLogger.class);
fileLogger.out.println("hi");
fileLogger.out.println("hi");
}
结果为
打开文件Demo.txt
关闭文件Demo.txt
说明Spring创建Bean对象以后自动执行初始化方法,Spring容器关闭时销毁对象,自动执行销毁方法
方式二:使用@Bean注解管理Bean组件时
在其initMethod和destroyMethod属性上标注生命周期管理方法名
测试代码:
Bean组件
package cn.tedu.demo;
import java.io.PrintWriter;
public class DemoLogger {
public PrintWriter out;
public void open() throws Exception {
out=new PrintWriter("DemoLogger.txt");
System.out.println("打开文件DemoLogger.txt");
}
public void close() throws Exception {
out.close();
System.out.println("关闭文件DemoLogger.txt");
}
}
配置文件
/*测试对象生命周期管理功能*/
@Bean(initMethod = "open",destroyMethod = "close")
public DemoLogger demoLogger(){
return new DemoLogger();
}
测试文件
@Test/*测试@Bean提供的对象声命周期管理*/
public void testDemoLogger(){
DemoLogger logger=a.getBean("demoLogger",DemoLogger.class);
logger.out.println("hi");
}
结果
打开文件DemoLogger.txt
关闭文件DemoLogger.txt
注意:使用@Scope注解时,每次使用都会创建一个对象,Spring为了避免崔村泄露,不会缓存对象的引用,所以Spring关闭时就无法处理对象的销毁方法
配置类就是个代理