AOP面向切面编程

AOP面向切面编程

也是一种编程思想。主要的工作就是对应用当中重复的代码进行横向抽取。在运行过程之中,采用的是动态代理技术把一些代码内容植入到应用当中。主要是植入到目标方法当中进行增强。

在Spring中有两种代理模式。(AOP就是基于动态代理来实现的,底层依赖于反射机制)

  • JDK原生 动态代理
    首先先在pom.xml里面映入c3p0依赖
<!--引入C3P0-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
/**
 * @author: admin
 * @date: 2021/3/4
 *
 * JDK 原生的
 *
 *   主要是对应用当中的业务层进行增强
 *   Proxy jdk的一个代理类
 *   使用该类中的一个方法 newProxyInstance() 构建目标对象的代理对象
 *   该方法中有三个参数:
 *          ClassLoader: 类加载器 要求和目标对象是一样的类加载器 固定写法
 *          Class<?> interfaces: 实现的接口,要求和目标对象中实现的接口一样  固定写法
 *          InvocationHandle: 代理的方式 如何对目标对象进行增强 接口 匿名内部类
 *          在该接口当中定义了一个抽象方法 invoke()
 *               在该方法中也有三个参数:
 *                   Object proxy: 代理的目标对象
 *                   Method method: 当前要执行的目标对象中的方法
 *                   Object[] args: 当前执行方法中用到的参数。
 */
@Component("proxy01")
public class Proxy01 {

    //定义一个方法
    public UserService getProxyUserService(UserService userService) {// UserService 接口 传入的参数值肯定是该接口的实现类
        UserService us = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), UserServiceImpl.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("queryUserByUsername该方法开始执行了。。。。");
                Object obj = method.invoke(userService, args);// 反射机制 queryUserByUsername
                System.out.println("queryUserByUsername该方法执行即将完毕。。。。。");
                return obj;
            }
        });
        return us;
    }

    /*@Autowired
    private UserService userService;*/

    public static void main(String[] args) throws SQLException {
        Proxy01 proxy01 = new Proxy01();
        UserService proxyUserService = proxy01.getProxyUserService(new UserServiceImpl());
        User user = proxyUserService.queryUserByUsername("小苏");
        System.out.println(user);
    }

}

  • 第三方插件 cglib代理
    首先在pom.xml里面引入cglib的依赖
<!--引入第三方cglib依赖-->
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

测试代码

/**
 * @author: admin
 * @date: 2021/3/4
 *
 * 测试 动态代理 第二种方式  cglib
 *
 * 原理: 不需要借助于接口,一般情况下在继承关系中 --->父子类
 * 要求: 目标类 不能是最终类  public final DemoClass {}  不能出现final
 * Enhancer  增强器类
 * create()  创建目标对象的代理对象
 * 参数:
 *      class 字节码对象  目标对象中的字节码对象
 *      callback  ----> MethodInterceptor接口  方法拦截器  代理的方式
 *               通过拦截器的方式实现对目标对象中的方法进行增强。
 *      采用匿名内部类的方式实现
 *      import net.sf.cglib.proxy.MethodInterceptor;
 *      MethodInterceptor定义了一个抽象方法
 *             intercept()  拦截方法
 *      拦截方法也有三个参数:
 *             Object proxy:  代理的目标对象
 *             Method method:  当前要执行的目标对象中的方法
 *             Object[] objects: 当前执行方法中用到的参数。
 *
 */
@Component("proxy02")
public class Proxy02 {

    // 定义一个方法
    public UserService getProxyUserService(UserService us){
        // us.getClass() 获取字节码对象
        UserService userService = (UserService) Enhancer.create(us.getClass(), new MethodInterceptor() {
            //intercept 拦截器
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("开启事务。。。");// connection.setAutoCommit()
                Object obj = method.invoke(us, objects);
                System.out.println("提交事务。。。"); // commit()
                return obj;
            }
        });
        return userService;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值