SpringBoot注解讲解(@Configuration)

1、@Configuration

该注解标注在一个类上表明该类是一个配置类

(1)编写配置类,通过配置类向IOC容器加入Bean对象

文件结构:

 首先创建一个User类,然后编写一个MyConfig配置类,在配置类中将User对象装入IOC容器中,代码如下:

package com.yjh.config;

import com.yjh.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

    @Bean
    public User user01()
    {
        User zhangSan = new User("张三",18);
        return zhangSan;
    }

}

此时,user01已经被装入IOC容器中,我们可以在MainApplication中输出容器中的内容,对MainApplication中的代码进行修改,通过ConfigurableApplicationContext对象的getBeanDefinitionNames()方法可以获得容器中所有的bean。

package com.yjh;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;


@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for(String beanName:beanDefinitionNames)
        {
            System.out.println(beanName);
        }
    }
}

在控制台中的搜索user01可以看到输出的内容中确实有user01,说明我们通过配置类将bean加入IOC中成功。

 (2)判断容器中的bean是否是单例的,两次从容器中获取对象,并判断这两个对象是否是同一个

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for(String beanName:beanDefinitionNames)
        {
            System.out.println(beanName);
        }
        
        //判断是否为单例
        User user1 = run.getBean("user01", User.class);
        User user2 = run.getBean("user01", User.class);
        System.out.println(user1==user2);
        
    }
}

控制台输出true,表明默认是单例的。

(3)@Configuration可以带参数proxyBeanMethods,从名字上翻译过来就是代理Bean方法,该参数有两个值true和false,默认是true。下面进行代码演示:

首先将配置类中@Configuration的proxyBeanMethods置为false,然后在主程序中获取配置类对象,通过配置类对象调用成员方法user01()创建User对象,最后对比该对象与容器中的bean对象是否为同一个,具体代码如下:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for(String beanName:beanDefinitionNames)
        {
            System.out.println(beanName);
        }

        //判断是否为单例
        User user1 = run.getBean("user01", User.class);
        User user2 = run.getBean("user01", User.class);
        System.out.println(user1==user2);

        /*
        * 测试proxyBeanMethods参数
        * */
        //获取配置类对象
        MyConfig myConfig = run.getBean("myConfig", MyConfig.class);
        //输出配置类对象
        System.out.println(myConfig);
        //配置类对象调用成员方法创建User对象
        User user3 = myConfig.user01();
        //判断该User对象与容器中的对象是否是同一个
        System.out.println(user3==user1);
    }
}

输出的结果:

 将配置类上的注解@Configuration的proxyBeanMethods置为true,重新再次跑一次主程序,结果如下:

 重点!!!

由上述输出的myConfig就可以发现当proxyBeanMethods置为true时,此时的对象是由CGLIB增强的代理对象,而并不是myConfig本身。

该代理对象在myConfig对象的基础上做了增强,在调用user01()成员方法时,该对象会先去容器中查找容器中是否已经有该bean,如果有则直接通过容器中的bean生成User对象,如果没有再通过成员方法创建对象。这也就是为什么当proxyBeanMethods为true时,两个对象相同,为false时,两个对象不同。

2、总结

 @Configuration添加在某个类上面,该类就是配置类。

@Configuration有个参数proxyBeanMethods,当该参数为ture时,生成的配置类对象是增强的代理对象,该模式称为Full模式。反之,称为Lite模式。

何时使用Full模式,何时使用Lite模式?

  • 配置 类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
  • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值