• 实现Spring底层机制(三)


    阶段4—实现BeanPostProcessor机制

    1.文件目录

    image-20240222142242669

    2.初始化方法实现

    1.编写初始化接口InitializingBean.java
    package com.sun.spring.processor;
    
    /**
     * 该接口有一个方法afterPropertiesSet是在依赖注入之后调用,即初始化方法
     * @author 孙显圣
     * @version 1.0
     */
    public interface InitializingBean {
        void afterPropertiesSet() throws Exception;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2.MonsterService.java实现初始化接口
    package com.sun.spring.component;
    
    import com.sun.spring.annotation.Autowired;
    import com.sun.spring.annotation.Component;
    import com.sun.spring.annotation.Scope;
    import com.sun.spring.processor.InitializingBean;
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    
    @Scope(value = "prototype") //指定是多例的
    @Component(value = "monsterService")//自定义注解,自动反射创建bean对象,如果指定了value则id为value否则为首字母小写
    public class MonsterService implements InitializingBean{
        //自定义注解,按照名字进行依赖注入
        @Autowired
        private MonsterDao monsterDao;
    
        public void m1() {
            monsterDao.hi();
        }
    
        //初始化方法
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("MonsterService 的初始化方法被调用!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    3.容器中的createBean方法增加初始化逻辑,判断对象类型是否是InitializingBean的子类型,如果是,则转换成初始化接口类型执行初始化方法

    3.后置处理器实现

    1.编写后置处理器接口BeanPostProcessor.java
    package com.sun.spring.processor;
    
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    public interface BeanPostProcessor {
        //这两个方法会对Spring容器的所有bean生效,切面编程
        //bean初始化方法前调用
        default Object postProcessBeforeInitialization(Object bean, String beanName){
            return bean;
        }
    
        //bean初始化方法后调用
        default Object postProcessAfterInitialization(Object bean, String beanName){
            return bean;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    2.在组件文件夹下编写后置处理器实现类SunBeanPostProcessor.java会被容器扫描
    package com.sun.spring.component;
    
    import com.sun.spring.annotation.Component;
    import com.sun.spring.processor.BeanPostProcessor;
    
    /**
     * 后置处理器,实现了自定义的后置处理器的接口
     *
     * @author 孙显圣
     * @version 1.0
     */
    //反射创建bean对象
    @Component
    public class SunBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            System.out.println("\n后置处理器postProcessBeforeInitialization被调用 bean类型=" + bean.getClass() + "bean名字=" + beanName);
            if (bean instanceof Car) {
                System.out.println("后置处理器发现这个类型是Car类型");
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            System.out.println("后置处理器postProcessAfterInitialization被调用 bean类型=" + bean.getClass() + "bean名字=" + beanName);
            return bean;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    3.容器类完整代码SunSpringApplicationContext.java
    package com.sun.spring.ioc;
    
    import com.sun.spring.annotation.Autowired;
    import com.sun.spring.annotation.Component;
    import com.sun.spring.annotation.ComponentScan;
    import com.sun.spring.annotation.Scope;
    import com.sun.spring.processor.BeanPostProcessor;
    import com.sun.spring.processor.InitializingBean;
    import org.apache.commons.lang.StringUtils;
    
    import java.io.File;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.Enumeration;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * 类似于Spring原生的ioc容器
     *
     * @author 孙显圣
     * @version 1.0
     */
    public class SunSpringApplicationContext {
        //传进来一个配置类的Class对象
        private Class configClass;
        //bean定义字段
        private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
        //bean对象字段
        private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();
        //定义一个属性ArrayList来存放后置处理器
        private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    
        //构造器,接收配置类的class对象
        public SunSpringApplicationContext(Class configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    
            //bean定义扫描,并将信息封装到beanDefinitionMap中
            this.beanDefinitionScan(configClass);
    
            //初始化单例池
            //1.获取所有bean的名字
            Enumeration<String> keys = beanDefinitionMap.keys();
            //2.遍历名字
            while (keys.hasMoreElements()) {
                String beanName = keys.nextElement();
                //3.是单例类型的就创建bean对象并放到单例池中
                BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
                if (beanDefinition.getScope().equals("singleton")) {
                    Object bean = createBean(beanDefinition, beanName);
                    //4.放到单例池
                    singletonObjects.put(beanName, bean);
                }
            }
    
        }
    
        public void beanDefinitionScan(Class configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            this.configClass = configClass;
            //一、获取要扫描的包
            //1.首先反射获取类的注解信息
            ComponentScan componentScan = (ComponentScan) this.configClass.getDeclaredAnnotation(ComponentScan.class);
            //2.通过注解来获取要扫描的包的路径
            String path = componentScan.value();
            System.out.println("要扫描的包=" + path);
    
            //二、得到要扫描包的.class文件对象,从而得到全路径进行反射
            //1.获取类加载器
            ClassLoader classLoader = SunSpringApplicationContext.class.getClassLoader();
            //2.获取要扫描包的真实路径,默认刚开始在根目录下
            path = path.replace(".", "/");
            URL resource = classLoader.getResource(path);
            //3.由该路径创建一个文件对象,可使用resource.getFile()将URL类型转化为String类型
            File file = new File(resource.getFile());
            //4.遍历该文件夹下的所有.class文件对象
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                System.out.println("==================================扫描所有组件==================================");
                for (File f : files) {
                    //反射注入容器
                    //1.获取所有文件的绝对路径
                    String absolutePath = f.getAbsolutePath();
                    //只处理class文件
                    if (absolutePath.endsWith(".class")) {
                        //2.分割出类名
                        String className = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1,
                                absolutePath.indexOf("."));
                        //3.得到全路径
                        String fullPath = path.replace("/", ".") + "." + className;
                        //4.判断是否需要注入容器,查看有没有自定义的注解Component
                        Class<?> aClass = classLoader.loadClass(fullPath);
    
                        //如果该类使用了注解Component则说明是一个spring bean
                        if (aClass.isAnnotationPresent(Component.class)) {
    
    
                            //后置处理器逻辑
                            //为了方便,将后置处理器放到ArrayList,原生的Spring容器中,对后置处理器还是放到的singletonObjects
                            //判断当前的class对象是否实现了后置处理器的接口
                            if (BeanPostProcessor.class.isAssignableFrom(aClass)) {
                                //如果实现了后置处理器的接口则转换成后置处理器类型
                                BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.newInstance();
                                //添加到ArrayList中
                                beanPostProcessors.add(beanPostProcessor);
                                //后面我们并没有用到单例池中的后置处理器,所以不需要将这个bean定义的信息放到map
                                continue;
                            }
    
                            System.out.println("这是一个Spring bean=" + aClass);
                            //将Bean的信息封装到BeanDefinition对象中并放入到beanDefinitionMap
                            BeanDefinition beanDefinition = new BeanDefinition();
                            //获取scope注解信息
                            Scope scopeAnnotation = aClass.getDeclaredAnnotation(Scope.class);
                            //只要scopeAnnotation是空的或者他不是空的但是值是空串,则返回singleon,否则就返回value
                            String scope = scopeAnnotation == null || scopeAnnotation.value().equals("") ?
                                    "singleton" : scopeAnnotation.value();
    
                            //封装信息到bean定义字段中
                            beanDefinition.setScope(scope);
                            beanDefinition.setClazz(aClass);
    
                            //获取Component注解的value值作为beanName
                            Component componentAnnotation = aClass.getDeclaredAnnotation(Component.class);
                            //只要component注解的值是空串就返回类名首字母小写,否则返回这个注解的值
                            String beanName = componentAnnotation.value().equals("") ?
                                    StringUtils.uncapitalize(className) : componentAnnotation.value();
    
                            //封装到beanDefinitionMap中
                            beanDefinitionMap.put(beanName, beanDefinition);
    
    
                        } else {
                            System.out.println("这不是一个Spring bean=" + aClass);
                        }
    
                    }
                }
    
            }
    
        }
    
        //根据bean定义对象来创建bean对象
        private Object createBean(BeanDefinition beanDefinition, String beanName) {
            //获取Class对象,反射创建实例
            Class clazz = beanDefinition.getClazz();
            try {
                Object instance = clazz.getDeclaredConstructor().newInstance();
                //进行依赖注入
                //1.遍历所有字段
                for (Field field : clazz.getDeclaredFields()) {
                    //2.判断字段中是否有autowired注解
                    if (field.isAnnotationPresent(Autowired.class)) {
                        //3.依赖注入
                        String name = field.getName();
                        Object bean = getBean(name);
                        //反射爆破
                        field.setAccessible(true);
                        field.set(instance, bean);
                        System.out.println(instance + "依赖注入完毕!");
                    }
                }
    
    
                //初始化方法逻辑
                //判断是否要执行Bean的初始化方法
                //存储instance
                Object result = instance;
                //查看这个对象是否实现了InitializingBean接口,instanceof判断是否是某个类型或者某个类型的子类型
                if (instance instanceof InitializingBean) {
                    //在初始化方法之前调用后置处理器的before方法,可以对容器的bean进行修改
                    for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
                        instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName);
                    }
                    //向上转型为接口类型并调用初始化方法
                    ((InitializingBean) instance).afterPropertiesSet();
                    //在初始化方法之后调用后置处理器的before方法,可以对容器的bean进行修改
                    for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
                        instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName);
                    }
                }
                //如果返回的instence是null,则返回之前存贮的结果
                if (instance == null) {
                    return result;
                }
    
                //如果成功则返回这个对象
                return instance;
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (NoSuchMethodException e) {
                throw new RuntimeException(e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
    
        }
    
        //返回容器中的对象
        public Object getBean(String name) {
            //如果是单例的,则从单例池中获取,如果是多例的则直接创建一个实例返回,名字没在bean定义中则抛出异常
            if (beanDefinitionMap.containsKey(name)) {
                BeanDefinition beanDefinition = beanDefinitionMap.get(name);
                //判断是否是单例
                if ("singleton".equals(beanDefinition.getScope())) {
                    //从单例池中获取对象
                    return singletonObjects.get(name);
                } else {
                    //直接创建对象(多例)
                    return createBean(beanDefinition, name);
                }
            } else {
                //name不在bean定义中则抛出异常
                throw new NullPointerException("没有该bean");
            }
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    4.结果展示

    image-20240222143316755

    4.该阶段完成的任务

    • 实现初始化方法
      • 编写初始化接口,里面有一个default的初始化方法
      • 编写初始化实现类,重写这个初始化方法
      • 在容器的依赖注入后添加初始化逻辑,当这个对象的类型是初始化接口的子类型的时候,就将其转换成接口类型并且调用初始化方法
    • 后置处理器实现
      • 编写一个后置处理器接口,里面有两个方法一个在初始化前调用,一个在初始化后调用
      • 在组件文件夹下编写后置处理器实现类
      • 在容器中beanDefinitionScan方法的扫描组件时添加后置处理器逻辑,如果该组件实现了后置处理器接口,则转换成后置处理器类型,并且放到ArrayList中方便查找
      • 在容器中的createBean方法增加后置处理器逻辑,在初始化方法之前和之后遍历存储后置处理器的ArrayList并分别执行方法

    阶段5—实现AOP机制&Spring底层机制总结

    1.实现AOP机制

    1.原理分析

    image-20240222151512245

    2.代码实现
    1.文件目录

    image-20240222164154334

    2.编写接口SmartAnimalable.java
    package com.sun.spring.component;
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    public interface SmartAnimalable {
        float getSum(float i, float j);
        float getSub(float i, float j);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    2.编写实现类SmartDog.java
    package com.sun.spring.component;
    
    import com.sun.spring.annotation.Component;
    import com.sun.spring.processor.InitializingBean;
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    @Component(value = "smartDog")
    public class SmartDog implements SmartAnimalable, InitializingBean {
        public float getSum(float i, float j) {
            float res = i + j;
            System.out.println("SmartDog-getSum=" + res);
            return res;
        }
    
        public float getSub(float i, float j) {
            float res = i - j;
            System.out.println("SmartDog-getSub=" + res);
            return res;
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("smartDog 被初始化!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    3.编写切面类SmartAnimalAspect.java
    package com.sun.spring.component;
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    public class SmartAnimalAspect {
        public static void showBeginLog() {
            System.out.println("前置通知");
        }
        public static void showSuccessLog() {
            System.out.println("返回通知");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    4.修改SunBeanPostProcessor.java对SmartDog的getSum方法进行动态代理
    package com.sun.spring.component;
    
    import com.sun.spring.annotation.Component;
    import com.sun.spring.processor.BeanPostProcessor;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 后置处理器,实现了自定义的后置处理器的接口
     *
     * @author 孙显圣
     * @version 1.0
     */
    //反射创建bean对象
    @Component
    public class SunBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            System.out.println("\n后置处理器postProcessBeforeInitialization被调用 bean类型=" + bean.getClass() + "bean名字=" + beanName);
            if (bean instanceof Car) {
                System.out.println("后置处理器发现这个类型是Car类型");
            }
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            System.out.println("后置处理器postProcessAfterInitialization被调用 bean类型=" + bean.getClass() + "bean名字=" + beanName);
            //实现AOP,返回代理对象
            if ("smartDog".equals(beanName)) {
                //使用jdk的动态代理返回代理对象
                /**
                 * ClassLoader loader,
                 * Class[] interfaces,
                 * InvocationHandler h
                 */
                //1.要代理的对象的类加载器
                ClassLoader classLoader = bean.getClass().getClassLoader();
    
                //2.要代理对象的接口信息
    
                Class<?>[] interfaces = bean.getClass().getInterfaces();
    
                //3.代理对象执行的方法,在代理对象执行所有的方法时都会调用
                InvocationHandler invocationHandler = new InvocationHandler() {
                    /**
                     * 代理对象执行的方法,在代理对象执行所有的方法时都会调用
                     *
                     * @param proxy 动态代理对象
                     *
                     * @param method 动态代理对象调用的方法
                     *
                     * @param args 方法的参数
                     *
                     * @return 返回method返回的结果
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //判断是不是getSum方法,如果是,则进行AOP处理
                        Object result = null;
                        if ("getSum".equals(method.getName())) {
                            //前置通知
                            SmartAnimalAspect.showBeginLog();
                            result = method.invoke(bean, args);
                            //返回通知
                            SmartAnimalAspect.showSuccessLog();
                        } else {
                            //如果不是getSum方法则正常执行原来的方法
                            result = method.invoke(bean, args);
                        }
                        return result;
                    }
                };
                //返回针对接口的代理对象(可以使用接口类型接收)
                return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
            }
            return bean;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    5.启动类
    package com.sun.spring;
    
    import com.sun.spring.component.MonsterService;
    import com.sun.spring.component.SmartAnimalable;
    import com.sun.spring.ioc.SunSpringApplicationContext;
    import com.sun.spring.ioc.SunSpringConfig;
    
    /**
     * @author 孙显圣
     * @version 1.0
     */
    public class AppMain {
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
            SunSpringApplicationContext ioc = new SunSpringApplicationContext(SunSpringConfig.class);
    
            //单例对象
            Object bean01 = ioc.getBean("monsterDao");
    
            //测试依赖注入
            MonsterService bean = (MonsterService) ioc.getBean("monsterService");
            System.out.println("==================================测试依赖注入调用方法==================================");
            bean.m1();
    
            //演示AOP
            System.out.println("==================================测试AOP==================================");
            SmartAnimalable proxy = (SmartAnimalable) ioc.getBean("smartDog");
            proxy.getSub(4,1);
            proxy.getSum(2,4);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    6.结果展示

    image-20240222164835898

    3.该阶段完成的任务
    • 编写接口,编写实现类并将实例交给Spring容器管理,编写切面类
    • 后置处理器中进行动态代理操作,这里是对SmartDog类型的getSum方法进行动态代理
      • 首先判断beanName是不是smartDog
      • 如果是则进行动态代理,invoke方法中先判断当前执行的方法是不是getSum
      • 如果是getSum则插入前置通知和返回通知,如果不是则正常执行这个方法

    2.Spring底层机制总结

    1.bean的生命周期
    • 反射创建bean对象
    • 依赖注入
    • 初始化bean
    • getBean
    • 销毁bean
    2.Spring容器的执行流程
    • 获取容器对象
    • 读取配置文件,得到要扫描的包
    • 扫描包下的组件,将bean定义信息放到Map中
    • 如果是单例
      • 反射创建bean对象,放到单例池中
      • 依赖注入(调用getBean)
      • 初始化bean
        • 初始化容器前调用后置处理器的before方法
        • 初始化容器之后调用后置处理器的after方法
    • 如果是多例
      • 在这个阶段什么都不做
    • getBean阶段
      • 如果是单例
        • 从单例池中获取bean对象
      • 如果是多例
        • 反射创建bean对象
        • 依赖注入(调用getBean)
        • 初始化bean
          • 初始化容器前调用后置处理器的before方法
          • 初始化容器之后调用后置处理器的after方法
        • 得到bean对象
    • 销毁bean
    3.动态代理和AOP的区别
    • 动态代理:针对的是某个对象所有方法
    • AOP:针对的是某些类型所有对象具体方法
    4.关于后置处理器 + 动态代理的理解
    • 后置处理器作用于Spring容器中所有类型,所有对象的初始化方法
    • getBean得到的就是后置处理器返回的bean
    • 当进入到后置处理器的时候
      • 获取切面类的所有信息
      • 将切入表达式与当前bean对象进行对比,只要类型匹配就进行动态代理
      • 使用动态代理进一步筛选要代理的方法,并根据不同的通知执行不同的操作,返回动态代理对象
      • 如果是不需要代理的方法,就不进行额外操作
    5.AOP的使用方式
    • 编写接口,接口对象(注解)(用于展示AOP的效果,因为没有对象)
    • 编写切面类(注解),切面对象(注解)
    • 通知 + 切点
    • 配置beans.xnl
      • 普通注解扫描
      • 开启AOP注解
    • 具体使用
      • 获取针对接口类型的代理对象(通过id或者接口类型获取)
      • 使用代理对象调用接口的方法
    • 四种通知
      • 前置通知
      • 返回通知
      • 异常通知
      • 后置通知
  • 相关阅读:
    @准大一萌新:学长学姐的N条忠告,字字珠玑,句句经典
    Windows安装SSH超详细教程
    Linux 网络请求和下载
    services.Jenkins Additional property tags is not allowed
    如何学习一门技术
    《HelloGitHub》第 90 期
    Adobe推出AI视频超分辨率工具VideoGigaGAN
    【Java面试指北】Exception Error Throwable 你分得清么?
    Python 小贴士(3)
    直播相关——声网rtc SDK
  • 原文地址:https://blog.csdn.net/m0_64637029/article/details/138140206