spring注解
来源:互联网 发布:淘宝大鼻子俄罗斯代购 编辑:程序博客网 时间:2024/06/06 18:42
- 注解的使用,首先编写一个注册文件Configure.java,并用@Configuration注解,然后使用注解容器类加载bean即可.
@Configuration@ComponentScan(basePackages = {"music"},excludeFilters = {@ComponentScan.Filter(value = MF.class)})public class Configure { @Bean public A excplicateBean(){ return new A(); }}//使用AnnotationConfigApplicationContext acfc = new AnnotationConfigApplicationContext(Configure.class);//web使用AnnotationConfigWebApplicationContext
- @ComponentScan,使用在配置类上,用于自动扫描bean.
//基本属性value/basePackages:指定一组要扫描的包,将扫描这些包及其子包下的文件.(默认基包为配置类所在的包)classes:直接指定扫描的一些类,这些类所在的包及其子包也会被扫描.nameGenerator:指定一个默认扫描组件的命名类,默认命名使用组件类名第一个字小写.excludeFilters:需要一组@ComponentScan.Filter的注解配置,每个@Filter可以配置一组过滤规则,多个@Filter可以基于正则/注解/具体类配置不同的过滤规则.includeFilters:反上.
- @ComponentScan.Filter,用于配置扫描过滤规则
属性如下
@Component,标记一个类为组件类,扫描时自动创建bean,创建顺序如下:
- 若该类有一个@AutoWired注解的构造器,则使用该构造器实例化,若没有则使用空白构造器实例化.(两者皆无则报错)
- 先注入注解在实例域上的@AutoWired/@Value.
- 再解析注解在实例方法上的@AutoWired/@Value
@Bean用在配置类的方法中,表示该方法会返回一个bean,beanId与方法名同,用于显式地配置一个bean.
@Configuration@ComponentScanpublic class Configure { @Bean //@Scope("prototype")未设置prototype则该方法会一直返回同一个单例 //singleton模式则第二次调用时直接返回已创建对象,不再执行new/set等方法 public A a(){ A a = new A(); a.setX(10); return a; } //相当于引用了a()产生的对象,a()在singleton模式下只返回单例 @Bean public B b1(){ return new B(a()); } //可以把其他bean放在参数中自动注入,好处是注入的bean可以来自xml配置/自动扫描 @Bean public B b2(A a){ return new B(a); }}@Bean创建bean的过程如下:1. 调用注解的方法产生一个实例对象,如果该方法有参数,则对参数注入.2. 如果返回对象的对应类的某些实例域上有@Value/@AutoWired注解,则对返回对象的这些实例域进行注入.3. 如果返回对象的对应类的某些方法上有@Value/@AutoWired注解,则对返回对象的这些方法进行注入.
@Import,用于导入另外一个配置类的信息到当前配置类.
@ImportResource,用于导入配置文件到当前配置类.
@Configuration@Import(Part1Config.class)@ImportResource("classpath:cd-config.xml")public class RootConfig{}//tips,如果需要导入一个java config到xml配置文件中,直接使用bean即可//<bean class="PartOneConfig.class"/>
- @Profile,用于配置不同环境下生成不同的bean.
可以用在@Component注解的自动扫描组件和@Bean注解的(方法)显式组件中,如果用在配置类上则表示所有经由该配置类产生的bean(显式/组件扫描)都有profile控制.
@Configurationpublic class Configure { //未配置profile则在所有环境下都会被创建 @Bean public ComponentDisc componentDisc(){ System.out.println("create bean cdisk"); return new SgtPers(); } @Bean //该bean只有在名为dev的profile激活时才能被创建 @Profile("dev") public DisckPlayer disckPlayer(){ DisckPlayer disckPlayer = new DisckPlayer(); disckPlayer.setDisc(componentDisc()); disckPlayer.setPlayTime(10); return disckPlayer; } @Bean //该bean只有在名为test的profile激活时才能被创建 @Profile("test") public DisckPlayer disckPlayer1(){ DisckPlayer disckPlayer = new DisckPlayer(); disckPlayer.setDisc(componentDisc()); disckPlayer.setPlayTime(12); return disckPlayer; }}通过两个参数可以选择激活哪些profiles:spring.profiles.active spring.profiles.default ;active未配置时生效当两个参数都没有配置时,则所有的profile限定bean都不被创建.参数可以在以下位置配置:As initialization parameters on DispatcherServletAs context parameters of a web applicationAs JNDI entriesAs environment variablesAs JVM system propertiesUsing the @ActiveProfiles annotation on an integration test class//在web.xml中配置<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value></context-param><context-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value></context-param><listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class></listener><servlet> <servlet-name>appServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet><servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern></servlet-mapping></web-app>
- @Conditional,配置条件bean,该注解需要传入一组Condition实现类,只有指定的所有Condition的实现类中的matches返回true,bean才能被创建.
tips:4.0以后@Profile使用@Conditional实现,对应的Condition实现类为ProfileCondition以下为ProfileCondition源码class ProfileCondition implements Condition { //所有的Condition实现类都能获得ConditionContext与AnnotatedTypeMetadata @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if (context.getEnvironment() != null) { MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if (attrs != null) { for (Object value : attrs.get("value")) { if (context.getEnvironment().acceptsProfiles(((String[]) value))) { return true; } } return false; } } return true; }}
- @Primary标记一个bean为主候选bean,用于解决自动注入的冲突.
@AutoWired是通过类型进行注入的,当同一个接口有多个实现,且都注册为bean时,spring无法选择哪个候选bean用于注入,此时通过将bean注解为@Primary,则注入有冲突时优先选择主候选bean.
- @Qualifier,用于缩小候选bean范围.
tips:@Qualifier("q")用于bean声明处(@Bean/@Component)时,表示限定该bean的选择范围为q.@Qualifier用于注入点(@Autowired)时,表示选择注解为@Qualifier("q")的bean进行注入或者使用id为q的bean注入.可以同时使用多个@Qualifier,进行更为详细的特征限定.@Bean@Qualifier("cold")public Dessert iceCream() { return new IceCream();}//选择候选名为cold的可能候选bean进行注入@Autowired@Qualifier("cold")public void setDessert(Dessert dessert) { this.dessert = dessert;}//由于java不允许在一个位置重复使用一个注解,所以当需要使用多个特征进行限定时则需要自定义注解。@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)//Spring扫描注解时,会解析注解上的注解并应用@Qualifier@interface Cold{}@Target({ElementType.METHOD,ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Qualifier@interface Soft{}使用时可以一起使用,进行多特征限定@Bean@Cold@Softpublic Dessert iceCream() { return new IceCream();}
- @Scope,用于控制bean的生成模式
代理模式的作用,考虑以下情况@Bean@Scope("prototype")public A a(){ return new A();}@Bean@Scope("singleton")public B b(){ return new B(a());}此时由于bean-b为单例模式,所以只创建一次,只调用一次a(),所以每次调用b.a.action(),实际调用的是同一个bean-a,如果希望每次调用b.a.action()都能使用新创建的A对象,那么必须配置一个proxyMode属性,它会创建一个A的代理类,当具体调用A类方法时,再调用getBean("a")从Spring容器中获得一个新创建的A,然后调用.最常用的情况是在scopeName为request/session,因为service层一般是单例,而request/session域的bean-rs是根据session/request创建、获取的,所以在启动时往service中注入rs是不可能的,只能先创建一个动态代理,当具体连接到来,再通过动态代理调用getBean("class-sessionId")获得具体不同的实例对象并调用具体方法。总而言之,proxyMode属性设置后,会延迟到属性/方法的调用时才会真正的去加载一个bean,每次调用都要重新加载,对于prototype,每次都返回新对象,request/session则返回对应的bean.
以下为proxyMode配置后的工作模式,可以看到通过注入一个动态代理,可以在一个单例中调用不同的注入对象。
- @PropertySource(“classpath:/com/soundsystem/app.properties”)+Environment用于加载properties文件的值.
tips:Environment除了可以使用getProperties加载资源还有getActivyProfiles等用于检测profiles的方法.@PropertySource("classpath:/com/soundsystem/app.properties")@Configurationclass Configure{ @Autowired Environment env; @Bean A a(){ return new A(env.getProperties("key","defaultValue")); }}
- @Value+PropertySourcesPlaceholderConfigurer实现属性占位符
//启用属性占位符@Beanpublic static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer();}class A{ //使用@Value("${key}")获取属性,并设置到属性上 A(@Value("${key}")String x){ this.x = x; }}
- SpEL,以#{…}为标志,内部为方法体.
class A{ //加载一个属性,与属性占位符同效果 @Value("#{systemProperties['key']}") private String x; //通过T操作符使用静态方法与静态域 @Value("T(System).currentTimeMillis()" private long time; //直接使用另外一个bean的方法/属性 @Value("b.getPoint()") private String point; //?.操作,只有在左部非空才往后调用,否则返回null,保证不会有NPE. @Value("b?.getPoint()?.toUpperCase()") private String dot; //+操作 @Value("p.firstName+'.'+p.sencodName") //正则判断 @Value("p.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'") //集合操作,取集合/数组中的第n个元素 @Value("singer.songs[1]") //.?[expression]根据expression的返回值过滤集合 @Value("singer.songs.?[name.contains('love')]") //.^[expression],选择集合中满足expression的第一个元素 @Value("singer.songs.^[getName() matches '*love*']") //.$[expression],选择集合中满足expression的最后一个元素 @Value("singer.songs.$[getName() matches '*love*']") //.![expression],根据expression的返回值形成新集合 @Value("singer.songs.![getName()]")}
SpEL支持的操作
0 0
- spring注解--组合注解
- Spring注解
- Spring注解
- Spring注解
- Spring注解
- Spring注解
- Spring 注解
- Spring注解
- Spring注解
- Spring注解
- spring 注解
- spring 注解
- spring注解
- Spring 注解
- Spring 注解
- spring 注解
- spring 注解
- spring 注解
- leetcode Sum of Two Integers
- mac osx 安装mysql步骤
- Java知识点1
- 探索CDN之一:初识CDN
- 服务器的写入和读取
- spring注解
- hdu3538(最短哈密顿路径)
- 麒麟堡垒机V1.31d发布
- 快速构造json字符串
- C++卷积神经网络实例:tiny_cnn代码详解(9)——partial_connected_layer层结构类分析(下)
- Android开发实用开源工具
- UIView
- Java8中的Lambda表达式概述
- RAID各级别及其特性