Spring
1.加载bean原理
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
//扫描applicationContext.xml,将其中的bean配置读入,并且用工厂生成对应的bean实例(最早期)
//现在更流行用注解,一个@Bean就搞定了
@Configuration//配置类====配置文件
@ComponentScan(value="com.yang.package")//扫描注解的路径
public class MainConfig{
@Bean
public Person person(){
return new Person("小杨",18);
}
}
ApplicationContext app = new AnnotationConfigApplicationContext("applicationContext.xml");
2.扫描
@ComponentScan(value="com.yang.package")
//bean相关
@Scope("singleton")//单实例。单实例在IOC容器创建的时候就会被创建,多实例在使用到的时候才会用到
@Scope("prototype")//多实例。
@lazy //懒加载,强制单实例在获取的时候才创建
//FactoryBean是spring中往容器中添加Bean时用到的,比普通注入多了可以获取Bean类型已经判断Bean是不是单例的作用
//BeanFactory是spring中获取Bean用到的
//条件加载Bean,windows系统时加载,非windows系统不加载
@Conditional(WinCondition.class)
@Bean
public Person person(){
return new Person("小杨",18);
}
public WinCondition implements Condition{
public boolean matches(ConditionContext context,AnnotatedTypeMetadata data){
String os_name = context.getEnvironment().getProperty("os.name");
if(os_name.contains("Windows")){
return true;
}
return false;
}
}
@Import(value={Dog.class,Cat.class})//也可以加到Bean工厂中而且是全类名的方式
//ImportSelector,ImportBeanDefinetionRigester 提供了更强大的导入方式
//FactoryBean注入到容器下面是一个例子
public class MyFactoryBean implements FactoryBean<MyBean>{
public MyBean getObject(){ return new MyBean();}
public Class<?> getObjectType(){return MyBean.class;}
public boolean isSingleton(){return true;}
}
@Bean
public MyFactoryBean myFactoryBean(){
return new MyFactoryBean ();
}
Bean的生命周期
方法一(重点掌握):
@Bean(initMethod="init",destoryMethod="destory")
public Bike bike(){return new Bike();}
class Bike{
public Bike(){}//构造函数先执行
public void init(){}//再执行初始化,以上两步都是在IOC容器创建完成之前做完的
public void destory(){}//IOC容器关闭时执行这个方法
}
方法二:
public Train implements initializingBean,disposableBean{
@override
public void afterPropertiesSet(){}//其实上面的init()底层调用的就是框架自己的afterPropertiesSet()
@override
public void destory(){}
}
方法三:
JSR250规范
public Jeep{
@PostConstruct
public void init(){}
@PreDestory
public void destory(){}
}
源码过程:
1。创建(单实例一开始就会创建,多实例不创建)
AbstractApplicationContext--->refresh()---->finishBeanFactoryInitialization()---->beanFactory.preInstantiateSingletons()---->getBean()-->doGetBean()---->getSingleton()拿不到会调用createBean()-->doCreateBean()返回的是BeanWrapper类型的对象,
-->createBeanInstance()如果有重用CGLIB来创建Bean,如果没有直接用java反射。
2。初始化
然后会调用populateBean()完成属性的注入initializeBean()给Bean初始化--->invokeInitMethods()调用我们指定的init方法(就是上面我们指定的那个方法)
3.bean的后置处理器(所有bean的处理都会被这个处理器拦截到)
public class YangBeanPostProcessor implements BeanPostProcessor{
//此方法在Bean指定的init 方法之前执行,
@override
public Object postProcessBeforeInitialization(Object bean,String beanName) throws BeansException{return bean;}
//此方法在Bean指定的init 方法之后执行
@override
public Object postProcessAfterInitialization(Object bean,String beanName) throws BeansException{return bean;}
}
其实,基本上所有的spring注解都是基于这个BeanPostProcessor来实现一系列的动作的!!!!
举个例子:
ApplicationContextAwareProcessor 也是个Bean处理器,用来检测类是否实现了一些接口,如果实现了接口就调用接口中的方法并把某些环境变量传到这个方法中
//比如我的Bean实现了一个叫ApplicationContextAware这个接口,顾名思义实现了这个接口的Bean可以知道应用的上下文信息(英语字面意思)
class MyBean implements ApplicationContextAware{
ApplicationContext app;
@override
public void setApplicationContext(ApplicationContext applicationContext ) throws BeansException{
this.app = applicationContext;//入参是spring框架中这个Bean相关的上下文对象
}
}
留个坑,spring中的异步处理器原理?AsyncAnnotationBeanPostProcessor
@Autowired @Severice @Inject @Qualify @Primary区别?
@Qualify(“指定id”)找Bean id---------明确指定
@primary
@autowired----------------自动装配
@value()放在吧Bean的属性上可以给这个属性装配一个默认值
@PropertySource(value="test.properties")修饰配置类,然后@Value("${key}")可以用
4Bean的生命周期
实例化
填充属性
调用BeanNameAware的setBeanName方法
调用BeanFactoryAware的setBeanFactory方法
调用ApplicationContextAware的setApplicationContext方法
调用BeanPostProcessor的预初始化方法
调用InitializingBean的afterPropertiesSet方法
调用自定义的初始化方法
调用BeanPostProcessor的初始化方法
实例化完毕