• SpringBoot SpringBoot 原理篇 1 自动配置 1.5 proxyBeanMethod


    SpringBoot

    【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】

    SpringBoot 原理篇

    1 自动配置

    1.5 proxyBeanMethod
    1.5.1 @ImportResource

    之前我们又完成了使用“工厂” 去创建bean 对象

    现在有个新问题又来了

    在这里插入图片描述

    现在的加载方式,有xml 配置文件,也有配置类,如果说我现在有一个十年前写的程序,它是用的配置文件加载的bean, 但是现在要上新功能,用注解写的,如果不能修改配置文件,那咋办?【典型的系统迁移问题:如何在一个新的注解开发的项目中使用老的配置文件的方式?可以实现吗?】

    【答案是当然的】

    来一个新的配置类

    package com.dingjiaxiong.config;
    
    import com.dingjiaxiong.bean.DogFactoryBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    
    /**
     * ClassName: SpringConfig32
     * date: 2022/10/24 13:40
     *
     * @author DingJiaxiong
     */
    
    
    public class SpringConfig32 {
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    其实啥也没有

    来一个新的运行类去加载32 这个配置类

    package com.dingjiaxiong.app;
    
    import com.dingjiaxiong.config.SpringConfig3;
    import com.dingjiaxiong.config.SpringConfig32;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * ClassName: App3
     * date: 2022/10/24 13:42
     *
     * @author DingJiaxiong
     */
    
    public class App32 {
    
        public static void main(String[] args) {
    
            ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig32.class);
    
            String[] names = ctx.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
            
        }
    
    }
    
    • 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

    直接运行看看效果

    在这里插入图片描述

    OK,没啥问题

    现在就来修改32 这个配置类,让它可以去加载到我们使用 xml 配置文件的方式做的bean

    其实特简单,一个注解

    package com.dingjiaxiong.config;
    
    import com.dingjiaxiong.bean.DogFactoryBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.ImportResource;
    
    /**
     * ClassName: SpringConfig32
     * date: 2022/10/24 13:40
     *
     * @author DingJiaxiong
     */
    
    @ImportResource("applicationContext1.xml")
    public class SpringConfig32 {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这是啥意思呢?就是说假定我们32 这个配置类还没写完,我现在就想拿xml 配置中的东西放到我们的配置类中

    OK,直接运行

    在这里插入图片描述

    效果很明显,都上来了

    这就是在现在的配置类中导入原始的配置文件的做法

    回顾一下

    • 加载配置类并加载配置文件(系统迁移)

    在这里插入图片描述

    1.5.2 proxyBeanMethod

    之前我们提了一下,@Configuration 这个注解和 @Component 这个注解很像,但是是假的

    看看两个注解的源码:

    @Component :

    在这里插入图片描述

    @Configuration:

    在这里插入图片描述

    注意看这最后一个【研究一下】

    再来一个新的配置类

    package com.dingjiaxiong.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    /**
     * ClassName: SpringConfig33
     * date: 2022/10/24 13:40
     *
     * @author DingJiaxiong
     */
    
    @Configuration
    public class SpringConfig33 {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    还是一个空壳

    再来一个新的运行类

    package com.dingjiaxiong.app;
    
    import com.dingjiaxiong.config.SpringConfig32;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * ClassName: App33
     * date: 2022/10/24 13:42
     *
     * @author DingJiaxiong
     */
    
    public class App33 {
    
        public static void main(String[] args) {
    
            ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig33.class);
    
            String[] names = ctx.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
    
        }
    
    }
    
    • 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

    直接运行看看效果

    在这里插入图片描述

    OK, 没啥问题

    看看这个bean 的类型

    System.out.println("=========================");
    System.out.println(ctx.getBean("springConfig33"));
    
    • 1
    • 2

    直接运行看看

    在这里插入图片描述

    这一串什么玩意儿

    意思就是SpringConfig33 其实是一个代理对象

    现在修改一下33 配置类

    在这里插入图片描述

    再次运行

    在这里插入图片描述

    效果很明显,那一串东西没了,就说明现在这个对象,已经不是一个代理对象了,就成了一个原始对象

    【所以这玩意儿的作用是什么?】

    我们在33 配置类中定义一个 bean

    package com.dingjiaxiong.config;
    
    import com.dingjiaxiong.bean.Cat;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    /**
     * ClassName: SpringConfig33
     * date: 2022/10/24 13:40
     *
     * @author DingJiaxiong
     */
    
    @Configuration(proxyBeanMethods = false)
    public class SpringConfig33 {
    
        @Bean
        public Cat cat(){
            return new Cat();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    直接再次运行

    在这里插入图片描述

    OK, 这没啥,上来了一个bean 对象

    现在我们直接用33 这个配置类,去调用这个方法

    package com.dingjiaxiong.app;
    
    import com.dingjiaxiong.config.SpringConfig32;
    import com.dingjiaxiong.config.SpringConfig33;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * ClassName: App33
     * date: 2022/10/24 13:42
     *
     * @author DingJiaxiong
     */
    
    public class App33 {
    
        public static void main(String[] args) {
    
            ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig33.class);
    
            String[] names = ctx.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
    
            System.out.println("=========================");
            SpringConfig33 springConfig33 = ctx.getBean("springConfig33", SpringConfig33.class);
            System.out.println(springConfig33.cat());
            System.out.println(springConfig33.cat());
            System.out.println(springConfig33.cat());
    
        }
    
    }
    
    • 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

    调了三次,而且把proxyBeanMethods 属性值改为了 true

    直接运行看看

    在这里插入图片描述

    可以看到,就是普通的bean对象,而且是单例的,即同一个对象

    如果改成false

    在这里插入图片描述

    好家伙,很明显,现在就不是单例的了【就成了完全不同的三个对象】

    意思就是如果proxyBeanMethods 属性为true,我们在运行对应的方法时,这个方法如果曾经在Spring 容器中加载过bean,那么我们再调,就是直接从容器中去拿了,而不是重新创建

    如果属性值为false【不创建代理对象】,就是使用当前类对象去执行它里面的方法,所以才有了三个不同的cat 对象【这就是true 和 false 的区别】

    【默认是true,即创建代理对象】

    看懂了这个,就可以解释我们前面遇到过的一个事情,学mq 的时候

    在这里插入图片描述

    我把这个注解一关,下面的东西就不能用了,但是我一开

    在这里插入图片描述

    因为proxyBeanMethods 属性默认为true,所以这就保证了我们每次都操作的 是同一个队列

    如果我明着写成配成false

    在这里插入图片描述

    这样就绑不对了,压根儿都不是同一个了

    OK,差不多就是这样

    回顾一下

    使用proxyBeanMethods=true可以保障调用此方法得到的对象是从容器中获取的而不是重新创建的

    在这里插入图片描述

  • 相关阅读:
    五.指针与结构体
    U-Boot常用命令
    给力心理平台项目开发介绍
    2024年GPLT团体程序设计竞赛题解(无L3-3)
    Oracle最终还是杀死了MySQL
    CSP-J 2021-网络连接
    能链科技获评中国最具投资价值企业榜单TOP10
    C++ primer 查漏补缺三 :初始化
    google hack常用语法介绍
    网页版的 Redis 可视化工具来了,已开源?
  • 原文地址:https://blog.csdn.net/weixin_44226181/article/details/128031661