@Conditional
是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean
//此注解可以标注在类和方法上 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { Class<? extends Condition>[] value(); }
从代码中可以看到,需要传入一个Class数组,并且需要继承Condition接口:
public interface Condition { boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2); }
Condition是个接口,需要实现matches方法,返回true则注入bean,false则不注入
@Scope
scope有singleton、prototype、request、session、global session作用域。
1.singleton单例模式,
全局有且仅有一个实例
2.prototype原型模式,
每次获取Bean的时候会有一个新的实例
3.request
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,
4.session
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
5.global session
global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用
request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可:
<listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener>
@DependsOn
https://blog.csdn.net/neweastsun/article/details/78775371
@Import
@Import注解的作用是给容器中导入组件,回顾下我们给容器中导入组件的方式,可以通过Spring的xm配置方式,可以通过注解,如@Component
等,也可以通过java配置类的方式给容器中导入注解,今天来介绍另一个注解,其作用也是给容器中导入组件,配置也很简单
@Configuration @Import({User.class,Car.class})//@Import导入组件,id默认是组件的全类名 public class Config { }
测试如下
public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class); String[] definitionNames = ac.getBeanDefinitionNames(); for (String name : definitionNames) { System.out.println(name); } }
当组件较多时,可以配合ImportBeanDefinitionRegistrar,ImportSelector使用
@ImportResource
相当于:
<import resource="applicationContext-*.xml" />
示例:
@Configuration @ImportResource("classpath:annotation/Context.xml") public class Config { @Value("${jdbc.url}") String url; @Value("${jdbc.driver}") String driver; @Value("${jdbc.password}") String password; @Value("${jdbc.username}") String username; /** * 必须有ImportResource注解 * @return * @throws PropertyVetoException */ @Bean("com") public ComboPooledDataSource getDataSource() throws PropertyVetoException { ComboPooledDataSource com=new ComboPooledDataSource(); com.setPassword(password); com.setDriverClass(driver); com.setUser(username); com.setJdbcUrl(url); return com; } }
@Role
指示给定bean的“角色”提示
可以直接或间接使用Component注释的任何类,也可以使用Bean注释的方法。
@PropertySources
用于加载配置文件到Spring的环境中
通过在类上设置@PropertySource
设置配置文件。
通过在成员变量上设置@Value
指定所设置在配置文件中的值。
@Configuration @PropertySource(value = "jdbc.properties")//引入配置文件 public class Config { @Value("${jdbc.url}") String url; @Value("${jdbc.driver}") String driver; @Value("${jdbc.password}") String password; @Value("${jdbc.username}") String username; }
通过在类上设置@PropertySource
设置配置文件。
在类上设置@ConfigurationProperties
自动将配置文件中名称满足的配置值设置。
@Component @PropertySource(value = "application.properties") @ConfigurationProperties(prefix = "demo") public class Message { private String msg; }
@ConfigurationProperties
是spring boot
中的类,需要导入相应的库。
@Profile
spring中@profile与maven中的profile很相似,通过切换配置来改变参数.
在同一个配置文件下:
/** * 容器配置类 * 用于测试@Profile注解 */ @Configuration @PropertySource(value = {"classpath:/dbconfig.properties"}) public class Config implements EmbeddedValueResolverAware { //数据库连接用户名 @Value(value = "${jdbc.username}") private String username; //数据库连接密码 private String password; //开发环境数据源 @Bean(value = "dataSourceDev") @Profile(value = "dev") public DataSource dataSourceDev(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev"); return comboPooledDataSource; } //测试环境数据源 @Bean(value = "dataSourceTest") @Profile("test") public DataSource dataSourceTest(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); return comboPooledDataSource; } //生产环境数据源 @Bean(value = "dataSourceProduction") @Profile("production") public DataSource dataSourceProduction(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException { ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); comboPooledDataSource.setUser(this.username); comboPooledDataSource.setPassword(this.password); comboPooledDataSource.setDriverClass(driverClass); comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/production"); return comboPooledDataSource; } //获取字符串解析器 @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { //解析配置文件,然后对数据库连接密码进行赋值 this.password = resolver.resolveStringValue("jdbc.password"); } }
@Test public void singleConfigProfile() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class); ac.getEnvironment().setActiveProfiles("dev"); ac.getBean("com"); }
在两个配置文件下
package annotation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import bean.Car; @Profile("Development") @Configuration public class Dev { @Bean("car") public Car getCar() { Car car=new Car(); car.setColor("green"); car.setName("dev"); return car; } }
package annotation; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import bean.Car; @Profile("Production") @Configuration public class Pro { @Bean("car") public Car getCar() { Car car=new Car(); car.setColor("grey"); car.setName("pro"); return car; } }
@Test public void doubleconfigProfile() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.getEnvironment().setActiveProfiles("dev");// 也可以是Pro ac.scan("annotation"); ac.refresh(); System.out.println(ac.getBean("car")); }
xml配置测试
<!-- 开发环境 --> <beans profile="dev"> <bean id="car" class="bean.Car"></bean> </beans> <!-- 生产环境 --> <beans profile="pro"> <bean id="car" class="bean.Car"></bean> </beans>
@Test public void xmlProfile() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("annotation/context.xml"); context.getEnvironment().setActiveProfiles("dev"); System.out.println(context.getBean("car")); //context.close(); }
@Primary
当一个接口有2个不同实现时,使用@Autowired注解时会报org.springframework.beans.factory.NoUniqueBeanDefinitionException异常信息
可以使用Qualifier注解,选择一个对象的名称,通常比较常用
也可以使用Primary,可以理解为默认优先选择,不可以同时设置多个
@Primary @Bean("car") public Car getCar1() { System.out.println("我是优先级最高的"); Car car=new Car(); car.setColor("white"); car.setName("first"); return car; } /** * 测试primary注解 * @return */ @Bean("car") public Car getCar2() { System.out.println("我不是优先级最高的"); Car car=new Car(); car.setColor("white"); car.setName("second"); return car; }
@Lazy
@Lazy注解用于标识bean是否需要延迟加载
默认是true,也就是说只要加了这个注解就会延迟加载
没加注解之前主要容器启动就会实例化bean
而加上@Lazy注解则必须在第一次调用的时候才会加载如下
@Lazy注解注解的作用主要是减少springIOC容器启动的加载时间
以下三个注解应该是在springboot中用的
@EnableMBeanExport
@EnableLoadTimeWeaving
@EnableAspectJAutoProxy
ProfileBeanConfig