1.2 注解@Import
-
该注解可以给容器导入很多的组件,有一个value属性,是Class的数组,所以可以 一下导入多个组件,该注解可以添加在组件类上面。具体使用如下,在MyConfig配置类上面添加该注解
package com.studymyself.config;
import ch.qos.logback.core.db.DBHelper;
import com.studymyself.bean.Pet;
import com.studymyself.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @Configuration:
* 1、在类上面添加该注解,告诉spring boot这个类是一个配置类,等同于容器的配置文件
* 2、当然,这个配置类的对象也是一个组件,被放到容器中。
* 3、注解中的属性:proxyBeanMethods,Boolean类型的
* 作用:代理Bean的方法
* 默认值:true
* 表示该注解修饰的类创建的对象会是一个进行功能增强了的代理对象
* 这个功能主要体现在调用下面方法获取对象时,会到容器中检查是否已经保存了这个类型的对象
* 没有则执行方法中创建对象的语句,有则不执行,直接获取该类型组件,保证单实例
*
* 设置为@Configuration(proxyBeanMethods = false):容器创建的该类对象不是代理对象,没有功能增强
* 也就不会有检查步骤,就是直接调用该类中的方法,每调用一次就执行创建对象的语句
*
* @Import:
* 可以使用在如@Configuration、@Controller等注解修饰的类上,对这个类没有任何作用
* 只是起到额外为容器添加组件的作用,一个value属性,Class类型的数组
* 使用方式:@Import({Xxx.class,Zzz.class,...})
*/
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false)
public class MyConfig {
/**
* @Bean:
* 1、放在方法上面表示给容器添加组件,组件值是返回的实例,默认将该方法名作为组件(返回的实例)的id,
* 2、通过测试,放进容器中的组件是单实例的
*/
@Bean
public User user01(){
User user = new User("张三");
return user;
}
@Bean
public Pet tomcat(){
Pet pet = new Pet("tomcat");
return pet;
}
}
-
在main主程序类中进行测试,获取我们所导入的组件
@SpringBootApplication
public class BSpringbootAnnotationApplication {
public static void main(String[] args) {
//获取容器对象
ConfigurableApplicationContext run = SpringApplication.run(BSpringbootAnnotationApplication.class, args);
//验证从容器中获取在配置类中添加的组件user01和tomcat
User user1 = run.getBean("user01",User.class);
Pet pet = run.getBean("tomcat",Pet.class);
System.out.println(user1+"\n"+pet);// User{name='张三'} Pet{name='tomcat'}
//再获取一次user01,跟第一次获取的比较,验证是否是同一个
User user2 = run.getBean("user01",User.class);
System.out.println(user1==user2);//true
//验证配置类也被创建对象作为组件放进容器中
MyConfig myConfig = run.getBean(MyConfig.class);
System.out.println(myConfig);
//com.studymyself.config.MyConfig$$EnhancerBySpringCGLIB$$767ae820@56febdc
//com.studymyself.config.MyConfig@4dd94a58
//验证@Configuration注解中属性proxyBeanMethods=true时,调用配置类中的方法
//这里就是代理对象调用方法
User user3 = myConfig.user01();
User user4 = myConfig.user01();
System.out.println(user3==user4);//true
//验证@Configuration注解中属性proxyBeanMethods=false时,调用配置类中的方法
//这里就是MyConfig的普通对象调用方法
// User user3 = myConfig.user01();
// User user4 = myConfig.user01();
// System.out.println(user3==user4);//false
//测试@Import注解导入的组件
System.out.println("====================");
String[] beanNamesForType = run.getBeanNamesForType(User.class);
for (String s:
beanNamesForType) {
System.out.println(s);
//com.studymyself.bean.User
//user01
}
DBHelper dbHelper = run.getBean(DBHelper.class);
System.out.println(dbHelper);//ch.qos.logback.core.db.DBHelper@7d151a
}
}
结果:
User{name='张三'}
Pet{name='tomcat'}
true
com.studymyself.config.MyConfig$$EnhancerBySpringCGLIB$$30e97cae@3b8ee898
true
====================
com.studymyself.bean.User
user01
ch.qos.logback.core.db.DBHelper@7d151a
从后三个结果可以看出,@Import注解导入的组件,在容器中的id是全限定类名,可以导入任意的组件
1.3 条件注解@Conditional
-
这个注解是一个根注解,它有很多的派生注解,这些派生注解(条件装配,不满足该注解中定下的条件,该注解的修饰的类或者方法返回的对象不会被装配到容器中)的具体功能如下图
-
这里找两个注解进行示例,首先是@ConditionalOnBean,使用方式:将该注解添加在MyConfig2的user02方法上面@ConditionalOnBean("tomcat2"),表示容器中必须有id为tomcat2的Pet组件实例,才会把user01方法返回的User实例作为组件放到容器中
@Configuration
public class MyConfig2 {
/**
* @ConditionalOnBean:条件装配注解
* 装配条件是容器中必须有该注解指定的组件
* (可以只用String集合name指定,也可以联合Class集合value指定,或者String集合的type来指定)才会有装配 的效果
*/
@ConditionalOnBean(name = "tomcat2",value = Pet.class)
@Bean
public User user02(){
User user = new User("李四");
return user;
}
//@Bean 让容器中不创建tomcat2的Pet组件
public Pet tomcat2(){
Pet pet = new Pet("tomcat2");
return pet;
}
}
-
main主程序中的测试代码如下
@SpringBootApplication
public class BSpringbootAnnotationApplication {
public static void main(String[] args) {
//获取容器对象
ConfigurableApplicationContext run = SpringApplication.run(BSpringbootAnnotationApplication.class, args);
//测试@ConditionalOnBean组件
//判断容器中是否有tomcat2的Pet组件
System.out.println(run.containsBean("tomcat2"));//false
//判断容器中是否有user02的User组件
System.out.println(run.containsBean("user02"));//false
}
}
结果:
false
false
注意:当我们放在类上面定义,针对的就是该类中的所有返回实例是否被装配,都受该注解的条件限制
1.4 注解@ImportResource("classpath:原先配置组件的配置文件地址")
当我们已经有xml的组件配置文件,不想在配置类中重新配置这些组件时,可以在配置类的上方添加该注解,属性值就是你原理配置文件的类路径
@Configuration
@ImportResource("classpath:spring.xml")
public class MyConfig2 {
/**
* @ConditionalOnBean:条件装配注解
* 装配条件是容器中必须有该注解指定的组件
* (可以只用String集合name指定,也可以联合Class集合value指定,或者String集合的type来指定)才会有装配 的效果
*/
@ConditionalOnBean(name = "tomcat2",value = Pet.class)
@Bean
public User user02(){
User user = new User("李四");
return user;
}
//@Bean 让容器中不创建tomcat2的Pet组件
public Pet tomcat2(){
Pet pet = new Pet("tomcat2");
return pet;
}
}