Core 的内容主要包括 IOC 和 AOP,Spring 有自己的 AOP 框架,能够解决 80% 的企业级应用的需求。(如果不够用)同时也提供集成 AspectJ 的方案。
原文:Foremost amongst these is the Spring Framework’s Inversion of Control (IoC) container. A thorough treatment of the Spring Framework’s IoC container is closely followed by comprehensive coverage of Spring’s Aspect-Oriented Programming (AOP) technologies. The Spring Framework has its own AOP framework, which is conceptually easy to understand and which successfully addresses the 80% sweet spot of AOP requirements in Java enterprise programming.
Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and certainly most mature AOP implementation in the Java enterprise space) is also provided.Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features — and certainly most mature AOP implementation in the Java enterprise space) is also provided.
AOP的术语不直观,但是为了避免术语混乱, Spring 也没有自己维护一套术语。这里整理下术语的概念。
原文
These terms are not Spring-specific. Unfortunately, AOP terminology is not particularly intuitive. However, it would be even more confusing if Spring used its own terminology.
形如 Transaction management
,在企业项目中,Transaction management
作为一个 Aspect
可以 跨多个类 对事务进行管理
原文:A modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in enterprise Java applications. In Spring AOP, aspects are implemented by using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (the @AspectJ style).
概念上有2种形式,在 Spring 中,往往指的是程序执行的链条中的某个方法
原文:A point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
这个概念,融合了上面两个名词。指的是在 Aspect
中某个 Join point
上执行的具体逻辑。有三种Advice 类型
Join point
前执行Before
和 After
的能力原文:Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception.
Spring 把 Advice
建模成 Interceptor
。围绕一个Join point
,可以建立多个 interceptor
这里有疑问:Spring MVC 中同时存在 Advice 和 Interceptor 结尾的类,他们是不是都是一个意思?
原文:Action taken by an aspect at a particular join point. Different types of advice include “around”, “before” and “after” advice. (Advice types are discussed later.) Many AOP frameworks, including Spring, model an advice as an interceptor and maintain a chain of interceptors around the join point.
用于路由到 Join point
(某个方法) 的具体规则,规则的描述默认使用
AspectJ pointcut expression
原文: A predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
被而外添加到(类)中的方法或字段
原文:Declaring additional methods or fields on behalf of a type. Spring AOP lets you introduce new interfaces (and a corresponding implementation) to any advised object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching. (An introduction is known as an inter-type declaration in the AspectJ community.)
被一个 Aspect
或多个 Aspect
增强的类。Spring 常常使用运行时的代理获取被增强的类。
动态代理的实现,可以是JDK dynamic proxy
或者 CGLIB proxy
编译时期、类装载时、运行时;根据目标对象产生增强的对象,这个过程就是 Weaving
。Spring 在运行时进行 Weaving
原文:linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.
与 AspectJ 的关系:
原文:Field interception is not implemented, although support for field interception could be added without breaking the core Spring AOP APIs. If you need to advise field access and update join points, consider a language such as AspectJ.
原文: Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable all uses of AOP within a consistent Spring-based application architecture. This integration does not affect the Spring AOP API or the AOP Alliance API. Spring AOP remains backward-compatible.
相关链接 >>
@Aspect
public class CommonPointcuts {
/**
* 切 com.xyz.myapp.service 包下的所有方法
*/
@Pointcut("within(com.xyz.myapp.service..*)")
public void inServiceLayer() {}
/**
* 接口在 com.xyz.myapp.abc.service
* 和 com.xyz.myapp.def.service 中
* 且实现类都在对应的 service (子)包下,
* 官网这里说的意思跟是否实现了接口无关,
* 只要关注service.*.子包的内容即可
*/
@Pointcut("execution(* com.xyz.myapp..service.*.*(..))")
public void businessService() {}
}
更多例子 >>
结合 Pointcut 表达式使用:
@Aspect
public class AfterReturningExample {
// Advice 上使用 Pointcut 表达式
@AfterReturning(
pointcut="com.xyz.myapp.CommonPointcuts.dataAccessOperation()",
returning="retVal")
public void doAccessCheck(Object retVal) {
// ...
}
}
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.CommonPointcuts.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
public interface Sample<T> {
void sampleGenericMethod(T param);
void sampleGenericCollectionMethod(Collection<T> param);
}
@Aspect
public class UsageTracking {
// 切 UsageTracked 接口的实现类,默认实现是 DefaultUsageTracked
@DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
public static UsageTracked mixin;
@Before("com.xyz.myapp.CommonPointcuts.businessService() && this(usageTracked)")
public void recordUsage(UsageTracked usageTracked) {
usageTracked.incrementUseCount();
}
}
Schema-based (类似于xml的配置文件形式)
@AspectJ-based(AspectJ 注解形式)
lower-level AOP(底层编程形式)
详情 >>
简单来说,就是先把bean用AOP增强,再加入到IOC容器
public class InstantiationTracingBeanPostProcessor implements BeanPostProcessor {
// simply return the instantiated bean as-is
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 可以在这里返回一个新的实例给IOC容器
// 注意,这里是所有bean初始化都会调这个方法
// 所以可以用自定义注解进行隔离(只操作自己关心的)
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("Bean '" + beanName + "' created : " + bean.toString());
return bean;
}
}
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="jdk*,onlyJdk"/>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
</list>
</property>
</bean>
原文:The BeanNameAutoProxyCreator class is a BeanPostProcessor that automatically creates AOP proxies for beans with names that match literal values or wildcards. The following example shows how to create a BeanNameAutoProxyCreator bean: