SpringBoot复习:2(@Configuration注解)

@Configuration注解

@Configuration注解的作用是代替以前我们使用的xml配置文件,被注解的类就是配置类,其内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
被@Configuration注解标注配置类本身也是一个组件。

基本使用

Pet类

/**
 * @author:小关同学爱吃汉堡
 * @date: 2021/4/5 17:41
 */
public class Pet {
    private String name;

    public Pet(){
    }

    public Pet(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                '}';
    }
}

User类

/**
 * @author:小关同学爱吃汉堡
 * @date: 2021/4/5 17:40
 */
public class User {
    private String name;
    private Integer age;

    private Pet pet;

    public Pet getPet() {
        return pet;
    }

    public void setPet(Pet pet) {
        this.pet = pet;
    }

    public User(){
    }

    public User(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

配置类
我们使用@Bean注解在方法上给容器注册组件,它默认是单实例的

import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author:小关同学爱吃汉堡
 * @date: 2021/4/5 17:44
 */
@Configuration(proxyBeanMethods = true)  //告诉SpringBoot这是一个配置类,
// 配置类本身也是一个组件
//proxyBeanMethods:代理bean的方法
//  Full(proxyBeanMethods = true)
//  Lite(proxyBeanMethods = false)
//  组件依赖
public class MyConfig {

    /**
     * @Bean注解标注的组件是单实例的
     * 在单实例下
     * 外部无论对配置类中的这个组件注册的方法调用多少次
     * 获取到的都是之前注册容器中的单实例对象
     * @return
     */
    @Bean
    //相当于xml文件中的bean标签,作用是给容器中添加组件,以方法名作为组件的id,返回类型就是组件类型
    //返回的值,就是组件在容器中的实例
    public User user01(){
        User user = new User("张三",19);
        user.setPet(pet01());
        return user;
    }

    @Bean("cat")//这里修改组件的id为"cat"
    public Pet pet01(){
        return new Pet("cat");
    }
}

启动类

import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import com.gcl.demo1helloworld.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;

@SpringBootApplication(scanBasePackages="com.gcl")
public class Demo1HelloworldApplication {

    public static void main(String[] args) {
        //返回IOC容器
        ConfigurableApplicationContext context = SpringApplication.run(Demo1HelloworldApplication.class, args);

        //从容器中获取组件
        Pet pet1 = context.getBean("cat", Pet.class);
        Pet pet2 = context.getBean("cat", Pet.class);
        //判断@Bean注解标注的组件是否是单实例的
        System.out.println("组件:"+(pet1==pet2));//结果返回true,可知@Bean标注的组件是单实例的

        MyConfig bean = context.getBean(MyConfig.class);
        //结果:com.gcl.demo1helloworld.config.MyConfig$$EnhancerBySpringCGLIB$$b19d16f6@7e97551f
        //从结果可以看出该配置类被SpringCGLIB增强了
        System.out.println(bean);

        //获取到的bean本身就是一个代理对象
        //如果@Configuration(proxyBeanMethods = true)中的proxyBeanMethods值为true
        //那么外部每次使用配置类的方法都会从容器中找组件,获取到的就是代理对象
        //否则获取到的就不是代理对象
        //当proxyBeanMethods = true时,结果为true,
        //当proxyBeanMethods = false时,结果为false,
        User user1 = bean.user01();
        User user2 = bean.user01();
        System.out.println(user1 == user2);


        //当proxyBeanMethods = true时,结果为true,
        //即:user.setPet(pet01());中的pet01()没有创建新的Pet对象,还是使用容器中已经加载好的Pet对象
        //当proxyBeanMethods = false时,结果为false,
        //即:user.setPet(pet01());中的pet01()创建了一个新的Pet对象,容器取消判断容器中是否有重复的组件
        User user = context.getBean("user01",User.class);
        Pet cat = context.getBean("cat",Pet.class);
        System.out.println(user.getPet()==cat);
    }
}

Full模式与Lite模式

Full模式

保证每个@Bean方法被调用多少次返回的组件都是单实例的
配置类组件之间有依赖关系,方法会被调用得到之前单实例组件

Lite模式

每个@Bean方法被调用多少次返回的组件都是新创建的
配置类组件之间无依赖关系,用Lite模式加速容器启动过程,减少判断容器中是否有相同组件的过程

关于更多Full模式与Lite模式的知识有一篇文章写得很好:
Spring的@Configuration配置类-Full和Lite模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值