spring中的@Configuration和@Bean关系

@Configuration和@Bean关系

在传统的bean.xml配置中配置bean的关系。@Configuration相当于这个bean.xml。@Bean相当与每一个配置的bean的信息。
在类上配置了@Configuration和不配置是不一样

  1. 在类配置了@Configuration在使用@Bean创建的都是单例的bean :这个被配置的类是通过cjlb的动态代理
  2. 问:如果没有配置@Configuration使用@Bean是否还会创建bean
  3. 如果会。那和配置了@Configuration有什么不一样
    案例:
    1.普通类
package com.kusen.spirnglean.bean;

/**
 * @description: 普通的用户类
 * @author: ghl
 * @create: 2021-09-29 09:40
 **/
public class User {
}

package com.kusen.spirnglean.bean;

/**
 * 测试类b 依赖与a 通过构造器的方式注入
 * @description: 测试依赖类B
 * @author: ghl
 * @create: 2021-09-29 10:22
 **/
public class ServiceB {
    private ServiceA serviceA;

    public ServiceB(ServiceA serviceA){
        this.serviceA=serviceA;
    }

    @Override
    public String toString() {
        return "ServiceB{" +
                "serviceA=" + serviceA +
                '}';
    }
}
package com.kusen.spirnglean.bean;

/**
 * @description: 测试依赖类A
 * @author: ghl
 * @create: 2021-09-29 10:22
 **/
public class ServiceA {
}

一:这里是@Bean的几种用法

package com.kusen.spirnglean.config;

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

/**
 *
 * @author ghl
 * @Configuration 相当于一个空bean.xml 的配置文件
 * @Bean 是一个个的bean的定义信息
 */
@Configuration
public class ConfigBean {
    /**
     * 默认的 bean的名称为 user1
     * @return
     */
    @Bean
    public User user1(){
        return new User();
    }

    /**
     * 指定的bean的名称
     * @return
     */
   @Bean("user2Bean")
    public User user2(){
        return new User();
    }

    /**
     * bean的获取指定的名称为 user3Bean 其他的是别名
     * @return
     */
    @Bean({"user3Bean","user4Bean","user5Bean"})
    public User user3(){
       return new User();
    }
}

配置了@Configuration和没有配置的区别

package com.kusen.spirnglean.config;

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

/**
 *
 * @author ghl
 * @Configuration 相当于一个空bean.xml 的配置文件
 * @Bean 是一个个的bean的定义信息
 */
 //配置了@Configuration
@Configuration
public class ConfigBean1 {
    /**
     * 默认的 bean的名称为 user1
     * @return
     */
    @Bean
    public User user1(){
        return new User();
    }

    /**
     * 指定的bean的名称
     * @return
     */
   @Bean("user2Bean")
    public User user2(){
        return new User();
    }

    /**
     * bean的获取指定的名称为 user3Bean 其他的是别名
     * @return
     */
    @Bean({"user3Bean","user4Bean","user5Bean"})
    public User user3(){
       return new User();
    }
}

在这里插入图片描述

package com.kusen.spirnglean.config;

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

/**
 *
 * @author ghl
 * @Configuration 相当于一个空bean.xml 的配置文件
 * @Bean 是一个个的bean的定义信息
 */
public class ConfigBean1 {
    /**
     * 默认的 bean的名称为 user1
     * @return
     */
    @Bean
    public User user1(){
        return new User();
    }

    /**
     * 指定的bean的名称
     * @return
     */
   @Bean("user2Bean")
    public User user2(){
        return new User();
    }

    /**
     * bean的获取指定的名称为 user3Bean 其他的是别名
     * @return
     */
    @Bean({"user3Bean","user4Bean","user5Bean"})
    public User user3(){
       return new User();
    }
}

在这里插入图片描述
小总结:有没有 @Confguraiton时。@Bean都会生效。区别不同的是。有@Confguration配置的类会创建 EnhancerBySpringCGLIB的代理类实现

有没有 @Confguraiton的区别

package com.kusen.spirnglean.config;

import com.kusen.spirnglean.bean.ServiceA;
import com.kusen.spirnglean.bean.ServiceB;
import com.kusen.spirnglean.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author ghl
 * @Configuration 测试相互依赖的配置信息
 * @Bean 是一个个的bean的定义信息
 */
@Configuration
public class ConfigBean3 {

    public ConfigBean3(){
        System.out.println("configBean3被创建了");
    }
    /**
     * 默认的 bean的名称为 serviceA
     * @return
     */
    @Bean
    public ServiceA serviceA(){
        System.out.println("调用serviceA()方法");
        return new ServiceA();
    }

    /**
     * 指定的bean的名称
     * @return
     */
   @Bean
    public ServiceB serviceB1(){
       System.out.println("调用了serviceB1方法");
       ServiceA serviceA = this.serviceA();
       return new ServiceB(serviceA);
    }

    /**
     * bean的获取指定的名称为 user3Bean 其他的是别名
     * @return
     */
    @Bean
    public ServiceB serviceB2(){
        System.out.println("调用了serviceB2方法");
        ServiceA serviceA = this.serviceA();
        return new ServiceB(serviceA);
    }
}


没有配置@Configuration代码

package com.kusen.spirnglean.config;

import com.kusen.spirnglean.bean.ServiceA;
import com.kusen.spirnglean.bean.ServiceB;
import com.kusen.spirnglean.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 *
 * @author ghl
 * @Configuration 测试相互依赖的配置信息
 * @Bean 是一个个的bean的定义信息
 */
 //这里注释了 @Configuration
//@Configuration
public class ConfigBean3 {

    public ConfigBean3(){
        System.out.println("configBean3被创建了");
    }
    /**
     * 默认的 bean的名称为 serviceA
     * @return
     */
    @Bean
    public ServiceA serviceA(){
        System.out.println("调用serviceA()方法");
        return new ServiceA();
    }

    /**
     * 指定的bean的名称
     * @return
     */
   @Bean
    public ServiceB serviceB1(){
       System.out.println("调用了serviceB1方法");
       ServiceA serviceA = this.serviceA();
       return new ServiceB(serviceA);
    }

    /**
     * bean的获取指定的名称为 user3Bean 其他的是别名
     * @return
     */
    @Bean
    public ServiceB serviceB2(){
        System.out.println("调用了serviceB2方法");
        ServiceA serviceA = this.serviceA();
        return new ServiceB(serviceA);
    }
}


测试类

package com.kusen.config;

import com.kusen.spirnglean.config.ConfigBean;
import com.kusen.spirnglean.config.ConfigBean1;
import com.kusen.spirnglean.config.ConfigBean3;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Arrays;

/**
 * @description: Configuration 测试类
 * @author: ghl
 * @create: 2021-09-29 10:03
 **/
public class ConfigurationTest {
    @Test
    public void test1(){
        AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(ConfigBean3.class);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            String[] aliases = context.getAliases(beanName);
            System.out.println(String.format("bean名称:%s,别名:%s,bean对象:%s",beanName,
                    Arrays.asList(aliases),context.getBean(beanName)));
        }
    }
}

总结:使用@Configuration注解spring会将这个配置类使用cjlb的方式创建一个代理类。每个@Bean创建的都是一个单例的对象放到ioc中。如果没有使用。@Bean不会创建单例。而是创建多个唯一的对象

你可能感兴趣的:(java,spring)