@Component/@Named:
@ComponentScan:
设置扫描的基础包:
@ComponentScan(basePackages ={"packageName","packageName"}) @Configuration public class config{}
@ComponentScan(basePackageClasses ={ClassName1.class,ClassName2.class}) @Configuration public class config{}
@Autowried/@Inject:
可以用到任何方法上,都会满足方法参数上的依赖
@Configuration:
作用声明配置类
@Configuration public Class javaConfig{ }
@Bean:
@Bean public InterfaceName funcationName(){ return new Implement(); }
@Bean(name="beanId") public InterfaceName funcationName(){ return new Implement(); }
注入
@Bean public CompactDisc sgtPeppers(){ return new SgtPeppers(); } 1. @Bean public CDplayer cdPlayer(){ return new CDplayer(sgtPeppers());} 2. @Bean public CDplayer cdPlayer(){ return new Cdplayer(CompactDisc compactDisc)}
声明Bean:
这种方式声明的Bean的id可能为完全限定名#0
<bean class="完全限定名"/>
设置id:
<bean class="完全限定名" id="id"/>
注意这里面我们并不会去检查完全限定名的合法性
构造器注入bean
使用bean的id注入Bean
<bean id="cdPlayer" class="soundsystem.CDPlayer"> <constructor-arg ref="compactDisc"/> </bean>
使用字面量注入
<bean id="compactDisc" class="soundsystem.BlankDisc"> <constructor-arg value="Sgt. Pepper`s Lonly Hearts Club Band"/> </bean>
使用<list><set>元素,注入
<bean id="" class=""> <constructor-arg> <list> <ref bean=""/> <ref bean=""/> </list> </constructor-arg> </bean>
<bean id="" class=""> <constructor-arg> <set> <value>Sgt. Pepper`s Lonly Hearts Club Band</value> <value>Sgt. Pepper`s Lonly Hearts Club Band</value> </list> </constructor-arg> </bean>
使用setter方法注入
使用bean的id注入
<bean id="" class=""> <property name="" ref="compactDisc"/> </bean>
使用字面量注入
<bean id="" class=""> <property name="" value="Sgt. Pepper`s Lonly Hearts Club Band"/> <property name=""> <list> <value>Sgt. Pepper`s Lonly Hearts Club Band</value> </list> </property> </bean>
Java配置混合Java配置和XML配置
Java配置混合Java配置
@Configuration public class CDConfig{ @Bean public CompactDisc compactDisc(){ return new SgtPeppers(); } } @Configuration @Import(CDConfig.class) public class CDPlayerConfig{ @Bean public CDPlayer cdPlayer(CompactDisc compactDisc){ return new CdPlaerImpl(compactDisc); } }
Java配置混合XML配置
<bean id="compactDisc" class="soundsystem.BlankDisc"/> @Configuration @ImportResource("classpath:cd-config.xml") public class CDPlayerConfig{ @Bean public CDPlayer cdPlayer(CompactDisc compactDisc){ return new CdPlaerImpl(compactDisc); } }
XML配置混合Java配置和XML配置
XML配置混合XML配置
<bean id="compactDisc" class="soundsystem.BlankDisc"/> <import resource="cdplayer-config.xml"/>
XML配置混合Java配置
<bean id="compactDisc" class="soundsystem.BlankDisc"/> <bean class="soundsystem.CDConfig"/>
环境控制profile
Java配置的环境控制使用@Profile
@Configuration public class DataSourceConfig{ @Bean @Profile("dev") public DataSource embeddedDataSource(){ return new DataSourceImpl1(); } @Bean @Profile("prod") public DataSource embeddedDataSource(){ return new DataSourceImpl2(); } }
XML配置的环境控制使用<beans>元素的profile属性
<beans profile="dev"> <bean id="dataSource" class="DataSourceImpl1"></bean> </beans> <beans profile="prod"> <bean id="dataSource" class="DataSourceImp21"></bean> </beans>
激活profile
到底激活哪个profile依赖两个属性
设置属性的方式
作为DispatcherServlet的初始化参数
<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> </servlet>
在集成测试类上,使用@ActiveProfiles注解设置
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes={PersistenceTestConfig.class}) @ActiveProfiles("dev") public class PersistenceTest{}
@Conditional
@Bean @Conditional(MagicExistsCondition.class) public MagicBean magicBean(){ return new MagicBean(); } 需要实现接口condition public class MagicExistsCondition implements Condition{ public boolean matchs(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment env = context.getEnvironment(); return env.containsProperty("magic"); } }
spring4中@Profile @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) @Documented @Conditional(ProfileCondition.class) public @interface Profile{ String[] value(); }
当有很多个相同接口实现的Bean的时候,spring进行注入,不知道该如何选择
使用@Primary标示首选的Bean,将会使用首选的Bean
@Component @Primary public class IceCream implements Desser{} @Bean @Primaryy public Dessert iceCream(){ return new IceCream(); } <bean id="iceCream" Class="IceCream" primary="true"/>
不能对多个Bean进行首选
使用@Qualifier限定自动装配的Bean
@Autowired @Qualifier("iceCream") public void setDessert(Dessert dessert){ this.dessert = dessert; }
@Qualifier里面的值就是限定符,一般使用@Component注解声明的类创建的Bean的id就是首字母小写的类名,而没有注明限定符的Bean,它的限定符就是id
如果后面重构了这个Bean的类名,那么后面将会注入失败,所以我们应该创建自定义的限定符
自定义限定符
@Component @Qualifier("iceCream") public class IceCream implements Desser{} @Autowired @Qualifier("iceCream") public void setDessert(Dessert dessert){ this.dessert = dessert; } 2. @Bean @Qualifier("iceCream") public Dessert IceCream(){ return new IceCream(); } ``` 2. 使用自定义的限定符注解 ```java @Target({ElementType.CONSTRUCTOR,Element.FIELD,ElementTeyp.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Cold{} @Component @Cold public class IceCream implements Desser{} @Autowired @Cold public void setDessert(Dessert dessert){ this.dessert = dessert; } ```
分类:
单例:
默认的作用域
原型:
@Component @Score(ConfigurableBeanFactory.SROPE_PROTORYPE) public class Notepad{}
@Bean @Score(ConfigurableBeanFactory.SROPE_PROTORYPE) public Notepad notepad(){ return new Notepad(); }
<bean in="notepad" class="com.myapp.Notepad" scope="prototype" />
会话/请求:
接口
@Component @Scope( value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES) public ShoppingCart cart(){}
实现类
@Component @Score( value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS) public class ShoppingCartImpl{}
分类:
使用Environment来注入
Enviroment
@Configuaration @PropertySource("classpath:/com/soundysystem/app.properties") //声明属性源 publci class ExpresssiveConfig{ @Autowired Environment env; @Bean public BlankDisc disc(){ return new BlankDisc(env.getProperty("disc.title"), evn.getProperty("disc.artist")); } }
2. Environement的其他用法
1. 获取属性值
1. String getProperty(String key); 2. String getProperty(String key); 3. T getProperty(String key, Class<T> type); 4. T getProperty(String key, Class<T> type, T defaultVlaue);
2. 检验是否存在
boolean containsProperty(String key);
3. 将属性解析为类
T getPropertyAsClass(String key, CompactDisc.class);
4. 检查profile处于激活状态
String[] getActiveProfiles();返回激活profile名称的数组 String[] getDefaultProfiles();返回默认profile名称的数组 boolean acceptsProfiles(String ... proflies);如果environment支持给定profile的话,就返回true
属性占位符
<context:propertyplaceholder/>声明使用占位符值注入 <bean id="sgtPepperts" class="sourdsystem.BlankDisc" c:_title="${disc.title}" c:_artist="${disc.artst}" />
publci BlankDisc( @Value("${disc.title}" title) ) { this.title = tile; } //声明使用属性值注入 @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); }
通知:定义切面在什么时候和做什么工作
织入:把切面应用到目标对象创建的代理对象的过程。织入的时间点有以下
基于动态代理,仅支持方法连接点,不支持字段和构造器的接入点
AspectJ指示器 | 描述 |
---|---|
execution | 用于匹配是连接点执行的方法 |
arg() | 限制连接点匹配参数为指定类型的执行方法 |
this() | 限制连接点匹配AOP代理的Bean引用为指定类型的类 |
target | 限制连接点匹配目标对象为指定类型的类 |
within() | 限制连接点匹配指定的类型 |
@annotation | 限定匹配带有指定注解的连接点 |
使用AOP的方法
package concert; public interface Performance{ public void perform(); }
使用使用的触发条件
execution(* concert.Performance.perform(...))
execution(* concert.Performance.perform(...) && within(concert.*))
execution(* concert.Performance.perform() and bean('woodstock')) 指定Bean execution(* concert.Performance.perform() and !bean('woodstock')) 指定除了的Bean
@Aspect public class Audience{ @Before("execution(** concert.Performance.perform(..)") public void silenceCellPhones(){ System.out.println("Silencing cell phones"); } @Before("execution(** concert.Performance.perform(..))") public void takeSeats(){ System.out.println("Taking seats"); } @AfterReturning("execution(** concert.Performance.perform(..))") public void applause(){ System.out.println("CLAP CLAP CLAP!!!"); } @AfterThrowing("execution(** concert.Performance.perform(..))") public void demandRefund(){ System.out.println("Demanding a refund"); } }
spring 使用AspectJ注解来声明通知方法
注解 | 通知 |
---|---|
@After | 通知方法会在目标方法返回或抛出异常后调用 |
@AfterReturning | 通知方法会在目标方法返回后调用 |
@AfterThrowing | 通知方法会在目标方法抛出异常后调用 |
@Around | 通知方法会将目标方法封装起来 |
@Before | 通知方法会在目标方法调用之前执行 |
使用@Poincut定义可重用的切点
@Aspect public class Audience{ @Pointcut("execution(** concert.Performance.perform(..") public void performance(){} @Before("performance()") public void silenceCellPhones(){ System.out.println("Silencing cell phones"); } @Before("performance()") public void takeSeats(){ System.out.println("Taking seats"); } @AfterReturning("performance()") public void applause(){ System.out.println("CLAP CLAP CLAP!!!"); } @AfterThrowing("performance()") public void demandRefund(){ System.out.println("Demanding a refund"); } }
启动自动代理功能
使用Java配置
@Configuration @EnableAspectJAutoProxy @ComponentScan public class ConcertConfig {}
使用XML配置
<aop:aspectj-autoproxy />