@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 />