侧边栏壁纸
博主头像
Ysfun博主等级

一名热爱技术、喜欢折腾的小小程序猿

  • 累计撰写 42 篇文章
  • 累计创建 14 个标签
  • 累计收到 21 条评论

目 录CONTENT

文章目录

SpringBoot2中-Configuration注解新增的proxyBeanMehtods属性详解

Ysfun
2022-06-17 / 0 评论 / 0 点赞 / 51 阅读 / 939 字

@Configuration(proxyBeanMethods = true/false)

1、Full模式(proxyBeanMethods=true)

proxyBeanMethods=true 为Full模式(默认为true),此时在spring IOC容器中的此配置类是一个CGLIB代理类,并且调用此配置类的@Bean方法产生的bean是单例的,即每次调用标有@Bean注解方法都会检查IOC容器中是否有该bean组件,如果没有则调用方法创建,否则就直接从IOC容器中获取。

测试代码

@Configuration(proxyBeanMethods = true)
public class ProxyBeanMethodTest {
    @Bean
    public User user(){
        return new User();
    }
}
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args){
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        ProxyBeanMethodTest bean = run.getBean(ProxyBeanMethodTest.class);
        System.out.println("配置类:"+bean);
        User user1 = bean.user();
        User user2 = bean.user();
        System.out.println("第一次调用配置类中的@Bean注解方法得到的bean组件:"+user1);
        System.out.println("第二次调用配置类中的@Bean注解方法得到的bean组件:"+user2);
    }
}

运行结果

两次调用user()方法得到的是同一个user对象

2、Lite模式(proxyBeanMethods=false)

proxyBeanMethods=false 为Lite模式,此时在spring IOC容器中此配置类就是一个普通的类,每次调用此配置类中标有@Bean注解的方法时都会在IOC容器中注册新的bean组件,调用@Bean方法时无需检查IOC容器中是否存在该bean组件,可以提高效率,加速容器启动

测试代码

@Configuration(proxyBeanMethods = false)
public class ProxyBeanMethodTest {
    @Bean
    public User user(){
        return new User();
    }
}
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args){
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        ProxyBeanMethodTest bean = run.getBean(ProxyBeanMethodTest.class);
        System.out.println("配置类:"+bean);
        User user1 = bean.user();
        User user2 = bean.user();
        System.out.println("第一次调用配置类中的@Bean注解方法得到的bean组件:"+user1);
        System.out.println("第二次调用配置类中的@Bean注解方法得到的bean组件:"+user2);
    }
}

运行结果

两次调用user()方法得到的是不同的User对象

3、Full模式和Lite模式优劣比较

Full模式可以很好地处理组件之间相互依赖的问题

@Configuration(proxyBeanMethods = true)
public class ProxyBeanMethodTest {

    @Bean
    public User user(){
        User user = new User();
        user.setDog(dog());
        return user;
    }

    @Bean
    public Dog dog(){
        return new Dog();
    }
}
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        
        User user = run.getBean(User.class);
        Dog dog1 = user.getDog();
        Dog dog2 = run.getBean(Dog.class);
        System.out.println(dog1 == dog2);
    }
}

由以上结果可以看出,IOC容器中的Dog与User的属性Dog是同一个对象,也更加印证了当为User对象注入Dog属性时,此Dog是从IOC容器中获取的,而并非重新调用了dog()方法。从上面的测试代码中也可以看出,使用Full模式可以确保IOC容器中同一类型的对象始终是同一个,可以很好的处理组件依赖问题。

Lite模式免去了每次调用方法前去IOC容器中检查的过程,可以有效加速容器启动过程

@Configuration(proxyBeanMethods = true)
public class ProxyBeanMethodTest {

    @Bean
    public User user(){
        User user = new User();
        user.setDog(dog());
        return user;
    }

    @Bean
    public Dog dog(){
        return new Dog();
    }
}
@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        
        User user = run.getBean(User.class);
        Dog dog1 = user.getDog();
        Dog dog2 = run.getBean(Dog.class);
        System.out.println(dog1 == dog2);
    }
}


4、结论

  • 配置类组件之间无依赖关系时使用Lite模式,可以省去检查容器中是否已经存在同类型组件的过程,加速容器启动
  • 配置类组件之间有依赖关系,使用Full模式,方法调用得到容器中的单实例组件

友情链接

视频讲解内容可参考尚硅谷-SpringBoot2讲解视频:https://www.bilibili.com/video/BV19K4y1L7MT?p=8

0

评论区