方式一: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

【 Spring 手动代理 】

注意:
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 已经整合以上两个内容

【 Spring 手动代理 】

目标类

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

【 Spring 手动代理 】

相关文章:

  • 2021-12-29
  • 2021-08-07
  • 2022-12-23
  • 2022-12-23
  • 2021-04-04
  • 2021-06-26
  • 2021-11-22
猜你喜欢
  • 2021-07-02
  • 2021-09-26
  • 2022-03-08
  • 2021-10-16
  • 2021-08-09
相关资源
相似解决方案