方式一:JDK 动态代理
目标类
package cn.ys.spring;
public interface UserService {
//切面编程
public void addUser();
public void updateUser();
public void deleteUser();
}
package cn.ys.spring;
public class UserServiceImpl implements UserService {
public void addUser() {
System.out.println("添加用户......");
}
public void updateUser() {
System.out.println("更新用户......");
}
public void deleteUser() {
System.out.println("删除用户......");
}
}
切面类
package cn.ys.aspect;
/**
* 切面类:增加代码 与 切入点 结合
*/
public class MyAspect{
public void before(){
System.out.println("开启事务...");
}
public void after(){
System.out.println("提交事务...");
}
}
工厂类
package cn.ys.factory;
import cn.ys.aspect.MyAspect;
import cn.ys.spring.UserService;
import cn.ys.spring.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyBeanFactory {
/**
* JDK实现代理
* @return
*/
public static UserService createUserService(){
//1.创建目标对象target
final UserService userService = new UserServiceImpl();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.把切面类2个方法 应用 目标类
//3.1 创建JDK代理,拦截方法
/*newProxyInstance(
ClassLoader loader, 类加载器,写当前类
Class<?>[] interfaces, 接口,接口的方法会被拦截
InvocationHandler h) 处理
*/
UserService seriviceProxy = (UserService) Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//开启事务
aspect.before();
//方法返回值是:业务方法的返回值
Object retObj = method.invoke(userService,args);
System.out.println("拦截返回值:" + retObj);
//提交事务
aspect.after();
return retObj;
}
}
);
return seriviceProxy;
}
}
测试类
package cn.ys.spring;
import cn.ys.factory.MyBeanFactory;
import org.junit.Test;
public class testSpring {
@Test
public void testSpringHello() throws Exception {
//自己实现AOP编程,使用JDK代理来实现
UserService userService = MyBeanFactory.createUserService();
userService.deleteUser();
userService.addUser();
userService.updateUser();
}
}
控制台打印
C:\Java\jdk1.8.0_181\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar=55292:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit5-rt.jar;C:\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\test-classes;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\classes;C:\Users\ys951\.m2\repository\org\springframework\spring-beans\4.3.19.RELEASE\spring-beans-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-context\4.3.19.RELEASE\spring-context-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-aop\4.3.19.RELEASE\spring-aop-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-core\4.3.19.RELEASE\spring-core-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-expression\4.3.19.RELEASE\spring-expression-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\ys951\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\ys951\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 cn.ys.spring.testSpring,testSpringHello
开启事务...
删除用户......
拦截返回值:null
提交事务...
开启事务...
添加用户......
拦截返回值:null
提交事务...
开启事务...
更新用户......
拦截返回值:null
提交事务...
Process finished with exit code 0
注意:
JDK 动态代理需要有接口 和 实现类;
而 cglib 增强字节码 ,只需要实现类即可。
方式二:cglib 增强字节码
- 没有接口,只有实现类。
- 采用字节码增强框架 cglib,在运行时 创建目标类的子类,从而对目标类进行增强。
- 导入jar包:
自己导包(了解):
核心:hibernate-distribution-3.6.10.Final\lib\bytecode\cglib\cglib-2.2.jar
依赖:struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib\asm-3.3.jar
spring-core…jar 已经整合以上两个内容
目标类
package cn.ys.spring;
public class StudentService {
public void delete(){
System.out.println("删除学生......");
}
public void add(){
System.out.println("add学生......");
}
public void update(){
System.out.println("update学生......");
}
}
切面类
package cn.ys.aspect;
/**
* 切面类:增加代码 与 切入点 结合
*/
public class MyAspect{
public void before(){
System.out.println("开启事务...");
}
public void after(){
System.out.println("提交事务...");
}
}
工厂类
package cn.ys.factory;
import cn.ys.aspect.MyAspect;
import cn.ys.spring.StudentService;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class MyBeanFactory {
/**
* cglib 实现代理
* @return
*/
public static StudentService createStudentService(){
//1.创建目标对象target
final StudentService studentService = new StudentService();
//2.声明切面类对象
final MyAspect aspect = new MyAspect();
//3.创建增强对象
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(studentService.getClass());
//设置回调【拦截】
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
/**
* proxy:
* cn.ys.service.StudentService$$EnhancerByCGLIB$$fbb8ef26
* proxy代理对象是StudentService的子类
*/
//System.out.println(proxy);
//System.out.println(methodProxy);
aspect.before();
//放行方法
//Object retObj = method.invoke(studentService,args);
Object retObj = methodProxy.invokeSuper(proxy,args);//解藕
System.out.println("拦截.....");
//System.out.println(proxy);
//System.out.println(methodProxy);
aspect.after();
return retObj;
}
});
//创建代理对象
StudentService serviceProxy = (StudentService) enhancer.create();
//System.out.println("serviceProxy);
return serviceProxy;
}
}
测试类
package cn.ys.spring;
import cn.ys.factory.MyBeanFactory;
import org.junit.Test;
public class testSpring {
@Test
public void testSpringCglib() throws Exception {
//实现AOP编程,使用cglib代理来实现
StudentService ss = MyBeanFactory.createStudentService();
ss.delete();
ss.update();
ss.add();
}
}
控制台打印
C:\Java\jdk1.8.0_181\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar=56354:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit5-rt.jar;C:\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\test-classes;C:\Users\ys951\Desktop\JavaSETest\JavaEE\Spring\target\classes;C:\Users\ys951\.m2\repository\org\springframework\spring-beans\4.3.19.RELEASE\spring-beans-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-context\4.3.19.RELEASE\spring-context-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-aop\4.3.19.RELEASE\spring-aop-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-core\4.3.19.RELEASE\spring-core-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\org\springframework\spring-expression\4.3.19.RELEASE\spring-expression-4.3.19.RELEASE.jar;C:\Users\ys951\.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\Users\ys951\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\ys951\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 cn.ys.spring.testSpring,testSpringCglib
开启事务...
删除学生......
拦截.....
提交事务...
开启事务...
update学生......
拦截.....
提交事务...
开启事务...
add学生......
拦截.....
提交事务...
Process finished with exit code 0