AOP:
通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
Aop中需要知道的要素:
切点:在执行的每一个方法都可以看作是一个切点
通知:就是我们需要扩展的功能代码
在切点之前增加的通知称之为前置通知
在切点之后增加的通知称之为后置通知
在切点之前和切点之后都增加的通知称之为环绕通知
在切点代码中有异常会执行的通知称之为异常通知
切面:有了切点+通知就可以织成切面
Aop实现的方式
A、Schema base
B、AspectJ
Schema base前置通知:
import java.lang.reflect.Method;
public class BeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
/**
*
* method:获得切点的方法对象
*
* objects:参数值
*
* o:切点所在的类
*
* */
System.out.println("前置通知");
}
}
Schema base后置通知:
package com.bjsxt.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterAdvice implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
/**
* o:切点返回值
*
* method:切点所在的方法对象
*
* objects:切点中参数
*
* o1:切点所在类
*
* */
System.out.println("后置通知");
}
}
Schema base环绕通知:
public class RunAdvice implements MethodInterceptor {
/**
* 环绕通知一般不结合前置和后置通知使用
*
* methodInvocation
* 封装是切点的方法对象和所在的类
*
* */
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("环绕通知---------前");
Object proceed = methodInvocation.proceed();
System.out.println("环绕通知---------后");
return proceed;
}
}
Schema base异常通知:
package com.bjsxt.advice;
public class ThrowsAdvice implements org.springframework.aop.ThrowsAdvice {
public void afterThrowing(Exception ex) throws Throwable {
System.out.println("--异常通知--");
}
}
Schema base通知XML配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="u" class="com.bjsxt.pojo.User"></bean>
<!--1.配置前置通知-->
<bean id="before" class="com.bjsxt.advice.BeforeAdvice"></bean>
<!--2.配置后置通知-->
<bean id="after" class="com.bjsxt.advice.AfterAdvice"></bean>
<!--3.配置环绕通知-->
<bean id="run" class="com.bjsxt.advice.RunAdvice"></bean>
<!--4.配置异常通知-->
<bean id="throws" class="com.bjsxt.advice.ThrowsAdvice"></bean>
<!--织如成一个切面-->
<aop:config>
<!--1.配置切点 含义:user中所有的b方法-->
<aop:pointcut id="pt1" expression="execution(* com.bjsxt.pojo.User.b(..))"/>
<!--1.配置切点 含义:user中所有的方法-->
<aop:pointcut id="pt2" expression="execution(* com.bjsxt.pojo.User.*(..))"/>
<!--1.配置切点 含义:pojo包中所以类的所以方法-->
<aop:pointcut id="pt3" expression="execution(* com.bjsxt.pojo.*.*(..))"/>
<!--2.配置通知-->
<aop:advisor advice-ref="before" pointcut-ref="pt1"></aop:advisor>
<aop:advisor advice-ref="after" pointcut-ref="pt1"></aop:advisor>
<aop:advisor advice-ref="run" pointcut-ref="pt1"></aop:advisor>
<aop:advisor advice-ref="throws" pointcut-ref="pt1"></aop:advisor>
</aop:config>
</beans>
AspectJ方式实现AOP:
package com.bjsxt.advice;
import org.aspectj.lang.ProceedingJoinPoint;
public class AspectJAdvice {
public void beforeAdvice(){
System.out.println("自己配置的前置通知");
}
public void afterAdvice(){
System.out.println("自己配置的后置通知");
}
public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
System.out.println("自己配置的环绕通知---------前");
Object o = point.proceed();
System.out.println("自己配置的环绕通知-----------后");
return 0;
}
public void throwsdvice(){
System.out.println("自己配置的异常通知");
}
}
AspectJ方式实现AOP的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--配置实体类-->
<bean id="u" class="com.bjsxt.pojo.User"></bean>
<!--配置通知-->
<bean id="AspectJ" class="com.bjsxt.advice.AspectJAdvice"></bean>
<aop:config>
<!--1.切点-->
<aop:pointcut id="pt" expression="execution(* com.bjsxt.pojo.User.a())"/>
<aop:aspect ref="AspectJ">
<aop:before method="beforeAdvice" pointcut-ref="pt"></aop:before>
<!--此方法:节点报错也会通知-->
<aop:after method="afterAdvice" pointcut-ref="pt"></aop:after>
<!--此方法:节点报错不会通知-->
<!-- <aop:after-returning method="afterAdvice" pointcut-ref="pt"></aop:after-returning>-->
<aop:around method="aroundAdvice" pointcut-ref="pt"></aop:around>
<aop:after-throwing method="throwsdvice" pointcut-ref="pt"></aop:after-throwing>
</aop:aspect>
</aop:config>
</beans>