aop(aspect oriented programming):
面向切面编程,在程序运行时,不改变程序源码的情况下,动态增强方法的功能。。常见场景:日志,事务,数据库操作。等。。解决模块化代码,解耦合。。。切面就是那些与业务无关,但大部分业务模块都会调用的公共逻辑
名词:
切面(Aspect):切点+通知
切点(Pointcut):切入点,匹配连接点的断言,通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行。。要添加代码的地方
连接点(Joinpoint):一个连接点总是表示一个方法的执行
通知(advice):向切点动态添加的代码前置通知 @Before后置通知 @After异常通知 @AfterThrowing返回通知 @AfterReturning环绕通知 @Around
代码:
package com.cj.controller;
import org.springframework.web.bind.annotation.*;
@RestController
public class HelloController {
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String hello(@RequestParam String name){
return "hello"+name;
}
@GetMapping("/hehe")
protected String hehe(){
return "hehe";
}
@GetMapping("/haha")
private String haha(){
return "haha";
}
}
@Aspect
@Component
public class WebLogAspect {
private final Logger logger= LoggerFactory.getLogger(this.getClass());
@Pointcut("execution(* com.cj.controller..*.*(..))")
public void controllerLog(){}
@Pointcut("execution(* com.cj.uiController..*.*(..))")
public void uiControllerLog(){}
@Before("controllerLog() || uiControllerLog()")
public void before(JoinPoint joinPoint){
// 获取request
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
logger.info("###########url : "+request.getRequestURL().toString());
logger.info("########http_method: "+request.getMethod());
logger.info("############ip"+request.getRemoteAddr());
logger.info("the args of the controller"+ Arrays.toString(joinPoint.getArgs()));
logger.info("##############class_method: " +joinPoint.getSignature().getDeclaringTypeName()+"---"+joinPoint.getSignature().getName());
}
}
引用:https://www.cnblogs.com/wangshen31/p/9379197.html
https://www.cnblogs.com/10fly/p/9921136.html
asm: assembly(汇编),一套java字节码生成框架,他可以直接对class文件进行增删改的操作(用来动态生成类或者增强既有类的功能)
aop底层是通过java动态代理和cglib(Code Generation Library)实现的区别:
java动态代理: 被代理类必须实现一个接口cglib:被代理的类可以是一个普通类(cglib底层实现是asm)
java动态代理 Proxy InvacationHandler
public class DynamicProxy {
interface IHello{
void sayHello();
}
static class Hello implements IHello{
@Override
public void sayHello() {
System.out.println("hello world");
}
}
static class InvocationHandlerImpl implements InvocationHandler{
Object originalObj;
Object bind(Object originalObj){
this.originalObj = originalObj;
return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(),originalObj.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("welcome");
return method.invoke(originalObj,args);
}
}
public static void main(String[] args) {
IHello helloProxy = (IHello) new InvocationHandlerImpl().bind(new Hello());
helloProxy.sayHello();
}
}
cglib
public class CglibDemo {
public void test(){
System.out.println("hello world");
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CglibDemo.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
System.out.println("before method run ");
Object result = proxy.invokeSuper(o, args);
System.out.println("after method run ");
return result;
}
});
CglibDemo cglibDemo = (CglibDemo) enhancer.create();
// cglibDemo.test();
cglibDemo.toString();
}
}



