栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

aop相关

aop相关

AOP

OOP(面向对象)的补充,降低代码耦合度
AOP 实现分类
1.静态AOP
AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
2.动态AOP
AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。

  1. 静态代理
  2. 动态代理:JDK和CGLIB
  3. Spring AOP
  4. Spring+AspectJ
静态代理
代理类和被代理的类实现了同样的接口,代理类同时持有被代理类的引用,这样,当我们需要调用被代理类的方法时,可以通过调用代理类的方法来做到
package com.example.kafka.tes;

import com.example.kafka.tes.service.UserService;
import com.example.kafka.tes.service.impl.DevelopImpl;
import com.example.kafka.tes.service.impl.UserServiceImpl;

public class MainProxyTest {
    public static void main(String[] args) {
        // 静态代理:代理方(DevelopImpl) / 被代理方(UserServiceImpl)
        UserService staticUserService = new DevelopImpl(new UserServiceImpl());
        staticUserService.addUser("test");
    }
}

自定义接口:UserService

package com.example.kafka.tes.service;

public interface UserService {
    boolean addUser(String userName);
    boolean delUser(Integer id);
}

被代理类:UserServiceImpl

package com.example.kafka.tes.service.impl;

import com.example.kafka.tes.service.UserService;

public class UserServiceImpl implements UserService {
    @Override
    public boolean addUser(String userName) {
        System.out.println("新增用户:"+userName);
        return true;
    }

    @Override
    public boolean delUser(Integer id) {
        System.out.println("删除用户id:"+id);
        return true;
    }
}

代理类:DevelopImpl

package com.example.kafka.tes.service.impl;

import com.example.kafka.tes.service.UserService;

public class DevelopImpl implements UserService {
    private UserService userService;
    public DevelopImpl(Object obj){
        this.userService = (UserService) obj;
    }
    @Override
    public boolean addUser(String userName) {
        System.out.println("Developer 完成后自己调用");
        userService.addUser("Developer");
        return false;
    }

    @Override
    public boolean delUser(Integer id) {
        System.out.println("Developer 完成后自己调用");
        userService.delUser(1000);
        return false;
    }
}

动态代理:JDK和CGLIB

1.JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
2.CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
区别:
JDK代理只能对实现接口的类生成代理;
CGlib是对类的实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类
service:

package com.example.kafka.tes.service;

public interface UserService {
    boolean addUser(String userName);
    boolean delUser(Integer id);
}

serviceImpl

package com.example.kafka.tes.service.impl;

import com.example.kafka.tes.service.UserService;

public class UserServiceImpl implements UserService {
    @Override
    public boolean addUser(String userName) {
        System.out.println("新增用户:"+userName);
        return true;
    }

    @Override
    public boolean delUser(Integer id) {
        System.out.println("删除用户id:"+id);
        return true;
    }
}

CGLIBProxy

package com.example.kafka.tes.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGLIBProxy implements MethodInterceptor {
    // CGlib需要代理的目标对象
    private Object targetObject;

    public Object createProxyObject(Object obj) {
        this.targetObject = obj;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object obj;
        // 过滤方法
        // 进行逻辑处理的函数
        if (method.getName().equals("addUser")){
            System.out.println("CGLIBProxy 增强 addUser() 方法!");
        }
        if (method.getName().equals("delUser")){
            System.out.println("CGLIBProxy 增强 delUser() 方法!");
        }
        obj = method.invoke(targetObject, args);
        return obj;
    }
}

JDKProxy

package com.example.kafka.tes.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxy implements InvocationHandler {
    private Object targetObject;

    public Object newProxy(Object targetObject) {
        // 将目标对象传入进行代理
        this.targetObject = targetObject;
        // 返回代理对象
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 进行逻辑处理的函数
        if (method.getName().equals("addUser")){
            System.out.println("JDKProxy 增强 addUser() 方法!");
        }
        if (method.getName().equals("delUser")){
            System.out.println("JDKProxy 增强 delUser() 方法!");
        }
        Object ret;
        // 调用invoke方法
        ret = method.invoke(targetObject, args);
        return ret;
    }
}

Test

package com.example.kafka.tes;

import com.example.kafka.tes.proxy.CGLIBProxy;
import com.example.kafka.tes.proxy.JDKProxy;
import com.example.kafka.tes.service.UserService;
import com.example.kafka.tes.service.impl.UserServiceImpl;

public class MainProxyTest {
    public static void main(String[] args) {
        UserService userManager = (UserService)new CGLIBProxy().createProxyObject(new UserServiceImpl());
        System.out.println("CGLibProxy:");
        userManager.addUser("liHaoZhen");

        System.out.println("JDKProxy:");
        JDKProxy jdkProxy = new JDKProxy();
        UserService userManagerJDK = (UserService)jdkProxy.newProxy(new UserServiceImpl());
        userManagerJDK.addUser("HaoZhen");
    }
}
Spring AOP

自定义切面(记录下日志)

package com.example.kafka.tes.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Aspect
@Component
public class CommonAspect {
    

    @Pointcut("execution(public * com..*.service.impl..*.*(..))")
    public void log() {
    }

    
    @Before("log()")
    public void Before(JoinPoint joinPoint) {
        Class aClass = joinPoint.getClass();
        System.out.println(aClass.getName());

    }
    
    @After("log() && @annotation(OperationLog)")
    public void After(JoinPoint joinPoint) {
    }

    
    @AfterReturning("log()")
    public void AfterReturning(JoinPoint joinPoint) {
        Class aClass = joinPoint.getClass();
        System.out.println(aClass.getName());

    }
    
    @AfterThrowing("log()")
    public void AfterThrowing(JoinPoint joinPoint) {
        Class aClass = joinPoint.getClass();
        System.out.println(aClass.getName());

    }
    
    @Around("@annotation(OperationLog)")
    public Object Around(ProceedingJoinPoint joinPoint,OperationLog OperationLog) throws Throwable {
        String name = OperationLog.name();
        System.out.println(name);
        long startTime = System.currentTimeMillis();
        //获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        // TODO 记录请求信息

        return joinPoint.proceed();

    }
    
    private Object getParameter(Method method, Object[] args) {
        List argList = new ArrayList<>();
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            //将RequestBody注解修饰的参数作为请求参数
            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
            if (requestBody != null) {
                argList.add(args[i]);
            }
            //将RequestParam注解修饰的参数作为请求参数
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (requestParam != null) {
                Map map = new HashMap<>();
                String key = parameters[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                map.put(key, args[i]);
                argList.add(map);
            } else {
                argList.add(args[i]);
            }
        }
        if (argList.size() == 0) {
            return null;
        } else if (argList.size() == 1) {
            return argList.get(0);
        } else {
            return argList;
        }
    }
}
 

自定义注解(切入点可以使用 @Pointcut注解指定 或 该自定义的注解)

package com.example.kafka.tes.aspect;

import java.lang.annotation.*;

@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OperationLog {
    String name();//调用接口的名称

    boolean intoDb() default false;//该条操作日志是否需要持久化存储
}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号