1.新建Maven项目,导入pom.xml所需依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>spring-aop</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
</dependencies>
</project>
2.新建需要进行动态代理的接口以及实现类和增强方法
package com.abchina.aop;
public interface TargetInterface {
public void method();
}
package com.abchina.aop;
public class Target implements TargetInterface {
public void method() {
System.out.println("Target Running....");
}
}
2.1新建测试类使用JDK自带的动态代理
package com.abchina.test;
import com.abchina.aop.TargetInterface;
import com.abchina.aop.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
public class AopTest {
@Test
public void testAop() {
final Target target = new Target();
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强代码...");
Object invoke = method.invoke(target, args);
System.out.println("后置增强代码...");
return invoke;
}
});
proxy.method();
}
}
2.2使用cglib动态代理
package com.abchina.test;
import com.abchina.aop.TargetInterface;
import com.abchina.aop.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
public class AopTest {
@Test
public void testCglibAop() {
final Target target = new Target();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Target.class);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("前置增强代码...");
Object invoke = method.invoke(target, objects);
System.out.println("后置增强代码...");
return invoke;
}
});
Target proxy = (Target) enhancer.create();
proxy.method();
}
@Resource
private TargetInterface target;
@Test
public void xmlAopTest() {
target.method();
}
}
3.使用xml方式配置AOP
3.1新建切面类
package com.abchina.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
public class MyAspect {
public void before() {
System.out.println("前置代码增强....");
}
}
3.2编写xml配置文件
3.2.1 配置目标类和切面类
<bean id="target" class="com.abchina.aop.Target"/>
<bean id="myAspect" class="com.abchina.aop.MyAspect"/>
3.2.2 织入切面
<aop:config>
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut="execution(public void com.abchina.aop.Target.method())"/>
</aop:aspect>
</aop:config>
3.2.3新建测试类测试AOP
package com.abchina.test;
import com.abchina.aop.TargetInterface;
import com.abchina.aop.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource
private TargetInterface target;
@Test
public void xmlAopTest() {
target.method();
}
}
4.使用注解方式配置AOP
4.1开启注解组件扫描和aop的自动代理
<context:component-scan base-package="com.abchina.aop"/>
<aop:aspectj-autoproxy/>
4.2 将目标类注册到spring容器中
@Component("target")
public class Target implements TargetInterface
4.3 将自定义的切面注册到spring容器中并配置切面
notice:切面可以注册在类上以及方法上,切面表达式可以简写
package com.abchina.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component("myAspect")
@Aspect
public class MyAspect {
@Before("execution(* com.abchina.aop.*.*(..))")
public void before() {
System.out.println("前置代码增强....");
}
}
5.源码链接