SpringBoot底层注解

添加组件

@Configuration

之前用spring-xml文件声明组件

 	<bean id="user01" class="com.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>
    <bean id="dog1" class="com.boot.bean.Pet">
        <property name="name" value="wangcai"></property>
   	</bean>

SpringBoot用@Configuration声明一个配置类

/**
 * 1.Configuration声明是配置类;配置类也是一个组件;
 * 2.@Bean修饰方法:注册组件,方法名是id,返回值是class;
 * 3.@Bean("name"):可以在注解里写明方法名,这样就不会用方法名做id了
 * 4.@Configuration(proxyBeanMethods=true):是否是代理bean的方式
 * */
@Configuration(proxyBeanMethods=true)
public class MyConfig {
    @Bean
    public User user01(){
        return new User("zhangsan",18);
    }
    @Bean
    public Pet dog1(){
        return new Pet("wangcai");
    }
}

组件注册方法调用是否获取单例bean

因为proxyBeanMethods=true,增强后springBoot会检查容器中是否已经有这个组件,没有再新建这个bean——为了保持单例bean。
这种情况下无论配置类中组件注册方法被调用多少次,都只会获取之前注册在容器里的单例bean

 	MyConfig bean = run.getBean(MyConfig.class);    //拿到配置类
    User user = bean.user01();
    User user1 = bean.user01();
    System.out.println("user:"+(user==user1));

结果:
user==user1是true
但是如果proxyBeanMethods=false,那结果就是false了。

所以什么时候代理为true,什么时候为false?

组件依赖:User组件依赖了Pet组件

public class User {
    private String name;
    private int age;
    private Pet pet;
}
@Configuration(proxyBeanMethods=true)
public class MyConfig {
    @Bean
    public User user01(){
        User user =  new User("zhangsan",18);
        user.setPet(dog1());        //User组件中有(依赖)Pet组件
        return user;
    }
    @Bean
    public Pet dog1(){
        return new Pet("wangcai");
    }
}
	User user2 = run.getBean("user01",User.class);
    Pet dog03 = run.getBean("dog1",Pet.class);
    System.out.println("用户宠物是否和容器中一致?"+(user2.getPet()==dog03));

Full模式(proxyBeanMethods=true):
在这里插入图片描述
Lite模式(proxyBeanMethods=fasle):
在这里插入图片描述

proxyBeanMethods的作用是:
springBoot会检查容器中是否已经有这个组件,容器中没有再新建这个bean。

因此两种模式使用的情况:
1.Full:组件依赖时以下代码能获取同一个pet——适用于有组件依赖的情况。
2.Lite:不是同一pet;但是会减少判断,启动起来快一些,因此适用于只注册组件,也没有组件依赖的情况

直接容器里取默认单例bean

默认单例bean:

	//返回IOC容器
	ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class,args);
	//从容器中获取组件
	Pet dog01 = run.getBean("dog1", Pet.class);
	Pet dog02 = run.getBean("dog1", Pet.class);
	System.out.println(dog01==dog02);

结果:
证明是单例bean,多次获取还是会返回一个bean
以前的@Bean,@Component,@Service,@Repository依旧可以用,和主程序类写在同级包下就可以扫描到。

@Import

可以导入一个数组的组件;可以是自己写的组件也可以是第三方组件。

/**
 * @Import({User.class, SimpleDBNameResolver.class}) IOC容器自动创建出这两种类型的组件,组件的名字就是全类名
 * */
@Import({User.class, SimpleDBNameResolver.class})
@Configuration(proxyBeanMethods=true)
public class MyConfig {
    @Bean
    public User user01(){
        User user =  new User("zhangsan",18);
        user.setPet(dog1()); 
        return user;
    }
}

主程序验证注入情况:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        //返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class,args);
       //拿到IOC容器中所有User类型的Bean
        String[] beanNamesForType =  run.getBeanNamesForType(User.class);   
        for (String s:beanNamesForType) {
            System.out.println(s);
        }
        System.out.println("---------------------------");
        //第三方组件是否创建成功
        SimpleDBNameResolver sdb = run.getBean(SimpleDBNameResolver.class);
        System.out.println(sdb);
    }
}

验证结果:
验证结果显然都创建成功

@Conditional 条件装配

满足条件则进行组件注入,可以写在类上也可以写在方法上。

以@ConditionalOnBean举例:

@Configuration(proxyBeanMethods=true)
public class MyConfig {

    //容器中有dog1这个名字的组件时,再注入user01这个组件
    @ConditionalOnBean(name = "dog1")
    @Bean
    public User user01(){
        User user =  new User("zhangsan",18);
        user.setPet(dog1());      
        return user;
    }
    //@Bean
    public Pet dog1(){
        return new Pet("wangcai");
    }
}

主程序:

public static void main(String[] args) {
        //返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class,args);
        boolean dog = run.containsBean("dog1");
        System.out.println("容器中有无dog1:"+dog);

        boolean user = run.containsBean("user01");
        System.out.println("容器中有无user01:"+user);
    }

答案:
容器中dog1没有注入,所以user01也不能注入

@ImportResource

导入原生spring配置文件
Ex.原来用xml文件声明的bean不想一个一个用@Bean去改,可以再要用xml里的bean的类上写@ImportResource注解指定xml位置后,就可以获取xml里的bean了。
原生配置——beans.xml:

	<bean id="user02" class="com.ttz.boot.bean.User">
        <property name="name" value="zhangsan"></property>
        <property name="age" value="18"></property>
    </bean>
    <bean id="dog2" class="com.ttz.boot.bean.Pet">
        <property name="name" value="wangcai"></property>
    </bean>

想调用beans.xml里bean的类写上@ImportResource后重新解析xml文件:

@ImportResource("classpath:beans.xml")
public class MyConfig {
	//略
}

主程序看是否解析xml:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        //返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class,args);
        System.out.println("------@ImportResource-------------");
        boolean dog2 = run.containsBean("dog2");
        System.out.println("容器中有无dog2:"+dog2);

        boolean user2 = run.containsBean("user02");
        System.out.println("容器中有无user02:"+user2);
    }
}

结果:
在这里插入图片描述

配置绑定

@ConfigurantionProperties

properties文件的属性一一解析到JavaBean中。
注意:适合核心配置文件application.properties绑定在一起

1.@Configuration+@Component:加在容器中

properties配置文件:

mycar.brand=BYD
mycar.price=100000

JavaBean:

//只有在容器中的组件才会拥有容器提供的功能,ex:配置绑定
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private  String brand;
    private Integer price;
    //省略构造方法,getter,setter和toString()
}

只有注册成组件之后,才能实现容器提供的配置绑定功能;
prefix = “mycar”:指的是匹配properties文件中的前缀为mycar的属性。

Controller看效果:

@ResponseBody
@Controller
public class HelloController {
    @Autowired
    Car car;	//解析完就已经放进容器里了,所以可以直接在容器中获取bean
    
    @RequestMapping("/car")
    public Car car(){
        return car;
    }
}

结果:
拿到了配置文件里的bean

2.@Configuration+@EnableConfigurationProperties:配置绑定开启

用于配置类
javaBean:

@ConfigurationProperties(prefix = "mycar")
public class Car {
    private  String brand;
    private Integer price;
    //省略构造方法,getter,setter和toString()
}

配置类:

@EnableConfigurationProperties(Car.class)
//1.开启car配置绑定功能
//2.把car组件自动注册到容器中
public class MyConfig {
	//略
}

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值