博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列教程——11编程实现AOP
阅读量:3960 次
发布时间:2019-05-24

本文共 3188 字,大约阅读时间需要 10 分钟。

Spring系列教程——11编程实现AOP

在开始本章之前,需要先理解上一节讲解的这一张图片。

在这里插入图片描述

文章目录

一.JDK动态代理实现

上一章我们讲到了,JDK动态代理实现对应的是接口+实现类

先创建一个切面类MyAspect:

package aspect;public class MyAspect {
public void before(){
System.out.println("before被执行了"); } public void after(){
System.out.println("after被执行了"); }}

接口IUserService:

package service;public interface  IUserService {
void addUser(); void deleteUser(); void updateUser();}

实现类UserServiceImpl:

package service;public class UserServiceImpl implements IUserService {
@Override public void addUser() {
System.out.println("添加User"); } @Override public void deleteUser() {
System.out.println("删除User"); } @Override public void updateUser() {
System.out.println("更新User"); }}

现在我们需要做的就是把切面类MyAspect的advice织入到UserServiceImpl的方法当中。那么具体就是获取UserServiceImpl的代理类来实现。

我们先创建一个工厂类来实现

public class UserServiceFactory {
public static IUserService createUserService(){
IUserService userService = (IUserService) Proxy.newProxyInstance(UserServiceFactory.class.getClassLoader(), UserServiceImpl.class.getInterfaces(), new InvocationHandler() {
@Override //proxy是代理,method是在实际调用方法时反射产生的,args是对应的参数 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MyAspect myAspect = new MyAspect(); myAspect.before(); Object retObj = method.invoke(new UserServiceImpl(), args); myAspect.after(); return retObj; } }); return userService; }}

newProxyInstance参数讲解:

ClassLoader loader, 类加载器,写当类

Class<?>[] interfaces, 接口,接口的方法会被拦截
InvocationHandler h 处理

测试代码:

IUserService userService = UserServiceFactory.createUserService();userService.addUser();System.out.println("-----");userService.deleteUser();System.out.println("-----");userService.updateUser();System.out.println("-----");

在这里插入图片描述

二.CGLIB实现

上一章我们讲到了,CGLIB实现动态代理对应的是只有类,没有接口

具体的原理就是:采用字节码增强框架 cglib(需要导包),在运行时 创建目标类的子类,从而对目标类进行增强。
jar包分享:

链接:https://pan.baidu.com/s/1J66jrMWMAdZCVCOGn6F33A

提取码:lzmd

在JDK代理的基础上我们对工厂类进行修改:

public class UserServiceFactory {
public static IUserService createUserService(){
//目标类 final IUserService userService = new UserServiceImpl(); //切面类 MyAspect myAspect = new MyAspect(); //增强类 Enhancer enhancer = new Enhancer(); //由于原理是实现目标类的子类来进行扩展 enhancer.setSuperclass(userService.getClass()); enhancer.setCallback(new MethodInterceptor() {
@Override //o是代理对象为UserServiceImpl的子类,method是对应调用的增强方法,objects是参数,methodProxy是代理方法 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
myAspect.before(); method.invoke(userService,objects); methodProxy.invokeSuper(o,objects); myAspect.after(); return null; } }); return (IUserService) enhancer.create(); }

在这里插入图片描述

我们发现

method.invoke(userService,objects);methodProxy.invokeSuper(o,objects);

上面两种方式都成功执行了,但是第二种方式更好因为实现了解耦的效果,而第一个却使用到了外面的userService这个类。

转载地址:http://qtlzi.baihongyu.com/

你可能感兴趣的文章