spring 为什么可以一统江湖

spring 为什么可以一统江湖

Inversion of Contro 简称IOC 是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。也就是面向接口编程的思想。
简单的说就是使用配置的方式,修改程序代码的实现。能灵活的切换代码,不用修改逻辑代码。其实就是解决硬编码创建对象的问题。

学习的路线设定

  • 了解有多少种方式添加对象到容器中

    这个很重要,在工作中经常出现类找不到的异常,熟悉这个的话,问题很容易找到。

  • 再从spring对一个类的处理的源码开始解析spring的原理

Spring配置有两种,详细法就可以参考一下Spring的使用教程。

xml配置与注解方式配置。其他本质是一样的。

  • xml
  • 配置类上加Configuration

扫描加载bean的规则有,这些不是很重要.

  • @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{}
  • @@Import(bgy.beanout.Fly.class) 单独加入
@Configuration
@Import(value = { Dog.class })
public class Cap6MainConfig {}
  • 实现ImportSelector
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})
  • 使用FactoryBean
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;
    }
}
  • 使用JamesImportBeanDefinitionRegistrar
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 类的。重点:开发时可以按需要自定义上下文。

spring 源码解析

从加载容器开始

      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();
            }

        }
    }

BeanPostProcessors

后置处理器接口,实现了这个接口类可以对所有的类初始化方法进行拦截处理,分别为: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;
    }
}

spring 应用组件扩展

待发布

猜你喜欢

转载自www.cnblogs.com/wolf12/p/10751232.html