1.通过注解实现
1.1导入依赖
XML
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
1.2定义注解
java
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation{
}
1.2定义切面类
java
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/*
* 切面类
**/
@Aspect
@Component
public class AnnotationAspect {
// 定义一个切点:所有被RequestMapping注解修饰的方法会织入advice
@Pointcut("@annotation(TestAnnotation)")
private void advicePointcut() {}
/*
* 前置通知
**/
@Before("advicePointcut()")
public void before() {
System.out.println("annotation前置通知");
}
@After("advicePointcut()")
public void after() {
System.out.println("annotation后置通知");
}
@AfterReturning(pointcut = "advicePointcut()")
public void afterReturning() {
System.out.println("annotation后置返回通知");
}
@AfterThrowing(pointcut = "advicePointcut()", throwing = "ex")
public void afterThrowing(Exception ex) throws Exception {
System.out.println("annotation异常通知");
System.out.println(ex.getMessage());
}
@Around("advicePointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object proceed = null;
if (!"".equals("admin")) {
System.out.println("annotation环绕前置");
proceed = pjp.proceed(pjp.getArgs());
System.out.println("annotation环绕后置");
}
return proceed;
}
}
2.jdk代理注解方式
2.1.定义接口
java
public interface TargetInteface {
void method1();
void method2();
int method3(Integer i);
}
2.2.实现接口
java
public class Target implements TargetInteface{
/*
* 需要增强的方法,连接点JoinPoint
**/
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
public int method3(Integer i) {
System.out.println("method3 running ...");
return i;
}
}
2.3.定义通知
java
public class TargetAdvice implements MethodInterceptor, MethodBeforeAdvice, AfterReturningAdvice {
/*
* 通知/增强
**/
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("前置环绕通知");
Object proceed = methodInvocation.proceed();
System.out.println("后置环绕通知");
return proceed;
}
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("后置返回通知");
}
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置通知");
}
}
2.4.书写配置文件
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="target" class="com.heaboy.aopdemo.aop.Target"/>
<bean id="targetAdvice" class="com.heaboy.aopdemo.aop.TargetAdvice"/>
<bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target"/> <!--被代理的类-->
<property name="interceptorNames" value="targetAdvice"/> <!--如果用多种增强方式,value的值使用逗号(,)分割-->
<property name="proxyTargetClass" value="false"/>
<property name="interfaces" value="com.heaboy.aopdemo.aop.TargetInteface"/> <!--target实现的接口-->
</bean>
</beans>
2.5启动测试
java
public class AopTest {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-aop.xml");
TargetInteface targetProxy = (TargetInteface) appCtx.getBean("targetProxy");
targetProxy.method1();
print(targetProxy);
}
}
3.cglib配置文件方式
3.1.定义被代理的类
java
public class Target {
public void method1() {
System.out.println("method1 running ...");
}
public void method2() {
System.out.println("method2 running ...");
}
/*
* 连接点JoinPoint
**/
public int method3(Integer i) {
System.out.println("method3 running ...");
int i1 = 1 / i;
return i;
}
}
3.2.定义Aspect
java
import org.aspectj.lang.ProceedingJoinPoint;
/*
* 切面类
**/
public class TargetAspect {
/*
* 前置通知
**/
public void before() {
System.out.println("conf前置通知");
}
public void after() {
System.out.println("conf后置通知");
}
public void afterReturning() {
System.out.println("conf后置返回通知");
}
public void afterThrowing(Exception ex) throws Exception {
// System.out.println("conf异常通知");
// System.out.println(ex.getMessage());
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
Object proceed = null;
if (!"".equals("admin")) {
System.out.println("conf环绕前置");
proceed = pjp.proceed(pjp.getArgs());
System.out.println("conf环绕后置");
}
return proceed;
}
}
3.3书写配置文件
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="target" class="com.heaboy.aopdemo.confaop.Target"/>
<bean id="targetAspect" class="com.heaboy.aopdemo.confaop.TargetAspect"/>
<!--proxy-target-class="true" 表示使用cglib代理.默认为false,创建有接口的jdk代理-->
<aop:config proxy-target-class="true">
<!--切面:由切入点和通知组成-->
<aop:aspect ref="targetAspect">
<!--切入点 pointcut-->
<aop:pointcut id="pointcut" expression="execution(* com.heaboy.aopdemo.confaop.*.*(..))"/>
<!--增强/通知 advice-->
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:around method="around" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
<aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
</beans>
3.4启动测试
java
public class AopTest {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-confaop.xml");
Target targetProxy = (Target) appCtx.getBean("target");
System.out.println(targetProxy.method3(1));
}
}