Inversion of Contro 简称IOC 是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。也就是面向接口编程的思想。
简单的说就是使用配置的方式,修改程序代码的实现。能灵活的切换代码,不用修改逻辑代码。其实就是解决硬编码创建对象的问题。
了解有多少种方式添加对象到容器中
这个很重要,在工作中经常出现类找不到的异常,熟悉这个的话,问题很容易找到。
再从spring对一个类的处理的源码开始解析spring的原理
xml配置与注解方式配置。其他本质是一样的。
扫描加载bean的规则有,这些不是很重要.
<bean id="person" class="com.enjoy.cap1.Person">
<property name="name" value="wolf"></property>
<property name="age" value="19"></property>
</bean>
或在Configuration类中使用
@Bean("person")
@@Component与@ComponentScan(value = "bgy.bean")
一般用这种,在类上加@Component就可以ComponentScan加载到容器中
@Component
public class Dog{}
@Configuration
@Import(value = { Dog.class })
public class Cap6MainConfig {}
public class MyImportSelector implements ImportSelector{
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata){
//返回全类名的bean
return new String[]{"com.enjoy.cap6.bean.Fish","com.enjoy.cap6.bean.Tiger"};
}
}
//把MyImportSelector当成bean导入
@Import(value = {ImportSelector.class})
public class JamesFactoryBean implements FactoryBean<Monkey>{
@Override
public Monkey getObject() throws Exception {
// TODO Auto-generated method stub
return new Monkey();
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Monkey.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
public class JamesImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/*
*AnnotationMetadata:当前类的注解信息
*BeanDefinitionRegistry:BeanDefinition注册类
* 把所有需要添加到容器中的bean加入;
* @Scope
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean bean1 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Dog");
boolean bean2 = registry.containsBeanDefinition("com.enjoy.cap6.bean.Cat");
//如果Dog和Cat同时存在于我们IOC容器中,那么创建Pig类, 加入到容器
//对于我们要注册的bean, 给bean进行封装,
if(bean1 && bean2){
RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);
registry.registerBeanDefinition("pig", beanDefinition);
}
}
}
小结:
实现的spring包为:spring-context。上下文容器类都是继承了AbstractApplicationContext 类的。重点:开发时可以按需要自定义上下文。
ApplicationContext applicationContext=new AnnotationConfigApplicationContext(myconfig.class);
// ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
上下文抽象类,此设计用的是模板方法设计模式, 在refresh里 固定好加载时的方法调用顺序。
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();//加载 bean的配置定义
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);//如果有配置类则添加配置类处理器,并将优先级排为最高
this.registerBeanPostProcessors(beanFactory);//注册其他的处理器,并设置好处理顺序。
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);//注册所有注入进来的bean实例到容器中
this.finishRefresh();
} catch (BeansException var9) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
后置处理器接口,实现了这个接口类可以对所有的类初始化方法进行拦截处理,分别为:postProcessBeforeInitialization,postProcessAfterInitialization
@Component
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//返回一个的对象(传过来的对象)
//在初始化方法调用之前进行后置处理工作,
//什么时候调用它: init-method=init之前调用
System.out.println("postProcessBeforeInitialization...."+beanName+"..."+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization...."+beanName+"..."+bean);
return bean;
}
}
待发布
原文:https://www.cnblogs.com/wolf12/p/10751232.html