谈谈对spring的理解

spring核心内容一说起来就是IOC和AOP两大功能,大概是这样:
IOC
控制反转,就是将本来自己要创建和维护的对象,交给容器去管理,将程序员从不同对象之间的复杂的依赖关系中解放出来了
操作上来说,就是将bean注册进容器,需要时从容器中获取,而不用自己去new
AOP
面向切面编程,一般用来解决一些交叉的业务,比如打印日志,事务等。AOP将要交叉的业务模块化,把本来要写在程序内的一些重复代码提取出来,并将这些模块在程序前后调用(注意不是实现将业务代码拼接,是调用,AOP底层实现是动态代理,就是代理对象通过调用目标对象的同名方法,并在调用前后加增强代码,所以有时候你所使用的bean可能是代理类而不是真正你自己注册入容器的bean)

深入来讲,涉及到两个东西,一个BeanDefinition还有一个后置处理器

说到BeanDefinition之前,先看一下spring容器的运行原理在这里插入图片描述
图中的1、2、3步是spring的启动阶段,我们可以看到,spring启动过程

  • Spring首先会扫描解析指定位置的所有的类得到Resources(可以理解为.Class文件)
  • 然后依照TypeFilter和@Conditional注解决定是否将这个类解析为BeanDefinition存放在bean定义注册表中
  • 最后在把一个个BeanDefinition取出实例化成bean放入bean的缓存池

BeanDfinition在这里就和Class类差不多,用于描述一个bean实例
https://www.zhihu.com/collection/314010519
所以spring运行原理中的第一步,即spring解析了所有的配置,并将解析出的类已BeanDefinition存入在BeanDefinitonMap中

接下来就是创建Bean,在创建bean的时候并不是我们通常所想的那样,直接创建对应的实例,而是spring根据我们的配置(比如需要开启事务)会通过代理返回一个代理类,这就是后置处理器做了工作。在这里插入图片描述
上图是spring容器提供的一些后置处理器接口,比如BeanPostProcessor就是支持在bean在初始化前后对bean进行处理
以下我们使用BeanPostProcessor返回当前Bean的代理对象
在这里插入图片描述

@Configuration//表明该类是一个配置类,相当于AppConfig.xml
@ComponentScan//用于配置扫描的包,默认是扫描该配置类所在的包及其子包
public class AppConfig {
}
public interface Calculator {
    int add(int a, int b);
}
@Component
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a+b;
    }
}
@Component
public class MyAspectJAutoProxyCreator implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
            return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        final Object obj = o;
        //如果当前经过BeanPostProcessors的Bean是Calculator类型,我们就返回它的代理对象,否则就返回他本身
        if(o instanceof Calculator){
            Object proxyObj = Proxy.newProxyInstance(
                    this.getClass().getClassLoader(),
                    o.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("开始计算...");
                            Object object = method.invoke(obj,args);
                            System.out.println((int)object);
                            System.out.println("计算结束...");
                            return object;
                        }
                    });
            return proxyObj;
        }
        return obj;
    }
}
public class TestPostProcess {
    public static void main(String[] args) {
        System.out.println("容器启动成功!");
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
        System.out.println("===============================================");
        Calculator calculator = (Calculator) applicationContext.getBean(Calculator.class);
        calculator.add(1, 1);
    }
}

在这里插入图片描述
把MyAspectJAutoProxyCreator类的注解@Component注释后,返回结果如下
在这里插入图片描述

发布了38 篇原创文章 · 获赞 8 · 访问量 3312

猜你喜欢

转载自blog.csdn.net/hcwdd/article/details/99204443