(1): Cut Point Interface Definition
org.springframework.aop.Pointcut
Interface is the central interface. Used to Advice(通知)定位到特定的类和方法
.
public interface Pointcut { ClassFilter getClassFilter(); MethodMatcher getMethodMatcher(); }
ClassFilter
Interface classes used to determine the cut point of action. If the matches()
method always returns true
, all the goals are matched.
public interface ClassFilter { boolean matches(Class clazz); }
MethodMatcher
Interface is usually more important.
public interface MethodMatcher { boolean matches(Method m, Class targetClass); boolean isRuntime(); boolean matches(Method m, Class targetClass, Object[] args); }
Most MethodMatcher
implementations are static, meaning that their isRuntime()
return false
. For this reason, the three parameters of the matches
method is never called.
`Note:
If possible, let the cut-off point for the static, allowing the AOP framework to cache the results point cut when an AOP proxy is created.
(2): cut-point operation
Spring supports operations have cut point joint (union) and the intersection (intersection). Joint means that the method can be any of a match, the intersection
It means that all the cut points are matched. However, the use AspectJ point expression
is generally easier.
AspectJExpressionPointcut
:AspectJ point expression
。
(3): it points to achieve Liqie
-
Static cut-off point (Static Pointcuts)
Based on static entry point
方法和目标类
, can not be considered a method parameter. For most purposes, the static and the best entry point enough. The first call method, Spring only assess a static entry point. After that, without the use of each method call to re-evaluate the starting point. -
Regular Expression entry point (Regular Expression Pointcuts)
-
JdkRegexpMethodPointcut
: JDK support for regular expressions. You can set up a list of regular expressions, either to meet that cut-off point for the assessmenttrue
.
-
-
Dynamic contact point (Dynamic Pointcuts)
Dynamic cut-off point to assess the cost of higher cost than static. Consider the method parameters and static information. This means that you must use every method call to evaluate them, and can not be cached, as arguments will vary.
-
Control flow tangent point (Control Flow Pointcuts)
And the AspectJ
cflow
similar.
(4): parent tangential point (Pointcut Superclasses)
Since static pointcuts
most useful StaticMethodMatcherPointcut
. Use example:
class TestStaticPointcut extends StaticMethodMatcherPointcut { public boolean matches(Method m, Class targetClass) { // return true if custom criteria match } }
2:Advice API in Spring
(1): Notification life cycle
Each is a notification Spring Bean
. 通知示例可以在所有通知对象之间共享
.
(2): Spring notification type
Around Advice (around advice)
Spring most basic advice is around advice. Use method interception
. Class implementation MethodInterceptor
.
public interface MethodInterceptor extends Interceptor { /** * Implement this method to perform extra treatments before and * after the invocation. Polite implementations would certainly * like to invoke {@link Joinpoint#proceed()}. * @param invocation the method invocation joinpoint * @return the result of the call to {@link Joinpoint#proceed()}; * might be intercepted by the interceptor * @throws Throwable if the interceptors or the target object * throws an exception */ Object invoke(MethodInvocation invocation) throws Throwable; } /** * Description of an invocation to a method, given to an interceptor * upon method-call. * * <p>A method invocation is a joinpoint and can be intercepted by a * method interceptor. */ public interface MethodInvocation extends Invocation { /** * Get the method being called. * <p>This method is a frienly implementation of the * {@link Joinpoint#getStaticPart()} method (same result). * @return the method being called */ Method getMethod(); } public interface Invocation extends Joinpoint { /** * Get the arguments as an array object. * It is possible to change element values within this * array to change the arguments. * @return the argument of the invocation */ Object[] getArguments(); } public interface Joinpoint { /** * Proceed to the next interceptor in the chain. * <p>The implementation and the semantics of this method depends * on the actual joinpoint type (see the children interfaces). * @return see the children interfaces' proceed definition * @throws Throwable if the joinpoint throws an exception */ Object proceed() throws Throwable; /** * Return the object that holds the current joinpoint's static part. * <p>For instance, the target object for an invocation. * @return the object (can be null if the accessible object is static) */ Object getThis(); /** * Return the static part of this joinpoint. * <p>The static part is an accessible object on which a chain of * interceptors are installed. */ AccessibleObject getStaticPart(); }
invoke () method of MethodInvocation
the parameters is disclosed a method is invoked, the target point of attachment, AOP parameters agents and methods. invoke () method should return the call: 连接点的返回值
.
Before Advice (pre-notification)
Simpler advice type is a before advice. You do not need to MethodInvocation
object. It is 进入方法之前调用
.
Pre-notification 主要优点不需要调用proceed()方法
, we will not inadvertently not continue to intercept chain.
public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method m, Object[] args, Object target) throws Throwable; }
Spring API design allows field provided prior notice, although the usual objects apply to field interception, but Spring is unlikely to achieve it. Please note that the return type void
. In advice can insert custom behavior before connecting point of execution but can not change until the return value. If before advice throws an exception, it will suspend further implementation of the interceptor chain. Abnormal propagated back to the interceptor chain.
返回所有方法的调用次数
public class CountingBeforeAdvice implements MethodBeforeAdvice { private int count; public void before(Method m, Object[] args, Object target) throws Throwable { ++count; } public int getCount() { return count; } }
Throws Advice (abnormality notice)
After returning abnormality notification connection point, the connection point if Ran abnormal, the notification is invoked. ThrowsAdvice
The interface is a marker interface, inherited AfterAdvice
. Examples are as follows: abnormal parameters must be present, other parameters like method, arguments exists, depends on whether you need.
public void afterThrowing(Exception ex){ } public void afterThrowing(RemoteException){ } public void afterThrowing(Method method, Object[] args, Object target, Exception ex){ } public void afterThrowing(Method method, Object[] args, Object target, ServletException ex){ }
note
不要抛出与目标签名方法不兼容的未声明的已检查异常
。
Rear return notification (After Returning Advice)
Rear return notice required to achieve `AfterReturningAdvice
`.
public interface AfterReturningAdvice extends Advice { void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable; }
Post notifications can be returned 访问返回值(但是它不能修改),被调用的方法,方法参数,目标对象
if it throws an exception,
It throws interceptor chain instead of the return value.
统计所有成功调用但是没有抛出异常的方法次数
public class CountingAfterReturningAdvice implements AfterReturningAdvice { private int count; public void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable { ++count; } public int getCount() { return count; } }
Introduction advice (Introduction Advice)
Introduction requires a IntroductionAdvisor
and IntroductionInterceptor
, to achieve the following
public interface IntroductionInterceptor extends MethodInterceptor, DynamicIntroductionAdvice { } public interface DynamicIntroductionAdvice extends Advice { /** * Does this introduction advice implement the given interface? * @param intf the interface to check * @return whether the advice implements the specified interface */ boolean implementsInterface(Class<?> intf); }
invoke()
Methods inherited AOP aopalliance MethodInterceptor
interface. If the method call on the interface introduced
The introduction interceptor is responsible for handling calls, it can not be called proceed()
.
Introducing notification can not be applied to any point of the cut. 它仅适用于类,而不是方法级别的。
Only IntroductionAdvisor
the introduction of notification use.
public interface IntroductionAdvisor extends Advisor, IntroductionInfo { ClassFilter getClassFilter(); void validateInterfaces() throws IllegalArgumentException; } public interface IntroductionInfo { Class[] getInterfaces(); }
Class contains only filter logic. getInterfaces()
Returns an interface section introduced. validateInterfaces()
A method for determining whether the interface is to be introduced into the IntroductionInterceptor
configuration.
Class DelegatingIntroductionInterceptor
is designed to be a proxy for actual interface to achieve the introduction of the introduced.
3:The Advisor API in Spring
In Spring, Advisor
it is contained only one 一个通知对象和一个切点表达式对象关联
of 切面
.
`DefaultPointcutAdvisor
`Most versatile advisor.
(2): Use ProxyFactoryBean
to create AOP proxies
The basic method of creating AOP proxy in Spring is to use ProxyFactoryBean
. He can completely control the entry points, as well as any applicable notice their order.
JavaBean properties
Some key property is inherited from ProxyConfig
.
-
proxyTargetClass
:如果代理的是目标类,而不是接口,该值为true。
Defaultfalse
. -
optimize
: Controls whether the agency will actively optimize application created by CGLIB. Unless you fully understand the relevant AOP optimization, otherwise this setting should not be used lightly. -
frozen
: If the proxy configuration is frozen, no longer allowed to change the configuration. The default isfalse
. -
exposeProxy
: Deciding whether to当前代理对象暴露到ThreadLocal中,以便可以被目标对象访问
. able to pass
AopContext.currentProxy()
Obtain.
Other attributes from ProxyFactoryBean
.
-
proxyInterfaces
: Agent array of interfaces. If not supported, the CGLIB agent is used. -
interceptorNames
: Interceptor array (Advisor
). These names exist in the current bean factory, a factory that contains the ancestors. -
singleton
: Decide whether to return the factory singleton object, by defaulttrue
.
(3): JDK and CGLIB agent
-
If a target object does not implement any interfaces, use CGLIB agent.
-
If a target object implements any interface, use the default JDK proxy
-
If a target object implements any interface, but the
proxyTargetClass
property istrue
, use GGLIB agent.
(4): Proxy Interface
interceptorNames
Property holds a list, this list is 拦截器(MethoInterceptor)
or ( Advisor
)
In the current factory bean names
.
注意:
You may be wondering why the list does not contain bean reference. The reason is that, if ProxyFactoryBean the singleton property is set to false, then it must be able to return independent proxy instances. If any of the consultant is itself a prototype, we need to return a separate instance, and therefore must be able to obtain an instance of the prototype from the factory. Holds a reference is not enough.
(5): Acting Class
Limitations CGLIB agent
-
final methods can not be notified. Because they can not be overridden
-
Spring3.2, CGOLIB repackaged in the spring-core jar.
(6):使用全局(Advisors)
By adding after the interceptor 星号
, the program adds advisor all bean name partially match the previous asterisk to the block in the chain. As follows:
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="service"/> <property name="interceptorNames"> <list> <value>global*</value> </list> </property> </bean> <bean id="global_debug" class="org.springframework.aop.interceptor.DebugInterceptor"/> <bean id="global_performance" class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor"/>
(7): Use ProxyFactory
to create AOP proxies
一个目标对象,一个通知,一个顾问。
@Bean public AspectJProxyFactory aspectJProxyFactory() { AspectJProxyFactory proxyFactoryBean = new AspectJProxyFactory(new UserService()); String expression = "execution(* com.ley.springboot.UserService.*(..))"; AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(expression); Advice advice = new UserServiceMethodBeforeAdvice(); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice); proxyFactoryBean.addAdvisor(advisor); return proxyFactoryBean; } @Bean(name = "proxyFactoryBean") public ProxyFactoryBean proxyFactoryBean() { ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); proxyFactoryBean.setTarget(new UserService()); String expression = "execution(* com.ley.springboot.UserService.*(..))"; AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression(expression); Advice advice = new UserServiceMethodBeforeAdvice(); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice); proxyFactoryBean.addAdvisors(advisor); return proxyFactoryBean; }
ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl); factory.addAdvice(myMethodInterceptor); factory.addAdvisor(myAdvisor); MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
(8): notification object manipulation
Advised
The interface is used to manipulate notification object.
Advisor[] getAdvisors(); void addAdvice(Advice advice) throws AopConfigException; void addAdvice(int pos, Advice advice) throws AopConfigException; void addAdvisor(Advisor advisor) throws AopConfigException; void addAdvisor(int pos, Advisor advisor) throws AopConfigException; int indexOf(Advisor advisor); boolean removeAdvisor(Advisor advisor) throws AopConfigException; void removeAdvisor(int index) throws AopConfigException; boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException; boolean isFrozen();
You can be added DefaultPointcutAdvisor,它持有一个pointcut和advised
. And it may be used to add any
Advisor
。
(9): Use auto-proxy
Strategy
-
BeanNameAutoProxyCreator
: This class is anBeanPostProcessor
automatically created based on the name of the bean AOPproxy.
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="jdk*,onlyJdk"/> <property name="interceptorNames"> <list> <value>myInterceptor</value> </list> </property> </bean>
-
DefaultAdvisorAutoProxyCreator
Versatile and more powerful auto proxy creator. The program will automatically add the application meets advisor in the current context, without the need to include specific bean name in the bean definition auto-proxy advisor's.该类在将相同建议一致的应用于许多业务对象很有用。例如跟踪或者性能监视方面。
(10): Define a new notification type
org.springframework.aop.framework.adapter
Package is a SPI
package, extended new notification type. Customize the new notification type only constraint is that it must implement the org.aopalliance.aop.Advice
marker interface.