首页 > 其他分享 >AOP

AOP

时间:2023-04-18 19:23:54浏览次数:26  
标签:Object System loginService AOP println public out

1.介绍

Aspect Oriented Programming 面向切面编程,将程序中的相同业务逻辑进行横向隔离,将重复的业务逻辑抽取到一个独立的模块。、

  • 连接点Joinpoint:程序执行过程中某个特定的节点
  • 通知Advice:在目标类连接点上执行的代码,有around,before等类型
  • 切点Pointcut:匹配连接点的断言,AOP通过其定位到连接点。
  • 目标对象Target:通知所作用的目标类。
  • 引介Introduction: 特殊的通知,为类添加属性和方法。动态地为业务类添加接口的实现逻辑。
  • 切面Aspect: 对系统中的横切关注点逻辑进行模块化封装的AOP概念实体。
  • 织入Weaving: 将通知添加到目标类具体连接点的过程,在编译,类加载,运行时完成,Spring动态代理织入,AspectJ编译期和类装载器织入。
  • 代理Proxy:目标类被织入增强后产生的结果类,融合了原类和增强的逻辑。

2.实现机制

2.1 JDK动态代理

JDK代理只能为接口创建代理实例

  • LoginService接口
public interface LoginService {
    public void login();
}
  • LoginServiceImpl
public class LoginServiceImpl implements LoginService{

    @Override
    public void login() {
        System.out.println("Login");
    }
}
  • PerformHandler类
public class PerformHandler implements InvocationHandler {
    private Object target;

    public PerformHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //增强的方法
        System.out.println("start");
        //执行被代理类的原方法
        Object invoke = method.invoke(target, args);
        System.out.println("end");
        return invoke;
    }
}
  • Test类
@Test
public void fun(){
    LoginService loginService = new LoginServiceImpl();
    //通过Proxy生成代理对象
    PerformHandler performHandler = new PerformHandler(loginService);
    loginService = (LoginService) Proxy.newProxyInstance(loginService.getClass().getClassLoader(),
            loginService.getClass().getInterfaces(),performHandler);
    loginService.login();
}

2.2 CGLib动态代理

CGLib动态代理为类创建实例 底层字节码技术 继承的方式实现
依靠Enhancer类创建代理实例 MethodInterceptor接口织入方法

  • CglibProxy
public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer = new Enhancer();

    //生成代理对象
    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    
    //回调方法 拦截目标类所有方法调用
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("start");
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println("end");
        return invoke;
    }
}
  • Test类
@Test
public void funG(){
    CglibProxy cglibProxy = new CglibProxy();
    //创建代理对象
    LoginServiceImpl loginService = (LoginServiceImpl) cglibProxy.getProxy(LoginServiceImpl.class);
    loginService.login();
}

3.实现方法

3.1 XML

  • spring.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd
            ">
 <bean name="loginService" class="service.LoginServiceImpl"></bean>
 <bean name = "xmlAdvice" class="service.XmlAdvice"></bean>
<!--   Spring Aop-->
   <aop:config>
<!--      切点-->
      <aop:pointcut id="pointcut" expression="execution(* service.LoginServiceImpl.*(..))"/>
<!--      切面-->
      <aop:aspect ref="xmlAdvice">
<!--         前置-->
         <aop:before method="before" pointcut-ref="pointcut"></aop:before>
<!--         返回-->
         <aop:after-returning method="afterReturning" pointcut-ref="pointcut"></aop:after-returning>
<!--         环绕-->
         <aop:around method="around" pointcut-ref="pointcut"></aop:around>
<!--         异常-->
         <aop:after-throwing method="afterException" pointcut-ref="pointcut"></aop:after-throwing>
<!--         后置-->
         <aop:after method="after" pointcut-ref="pointcut"></aop:after>
      </aop:aspect>
   </aop:config>
</beans>
  • Test类
@Test
public void funXml(){
    ApplicationContext context = new ClassPathXmlApplicationContext("config/spring1.xml");
    LoginService loginService = context.getBean("loginService", LoginService.class);
    loginService.login();
}

3.2 注解

  • Spring.xml 修改
    <bean name="annoAdvice" class="service.AnnoAdvice"></bean>
<!--    自动动态代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 <bean name="loginService" class="service.LoginServiceImpl"></bean>
  • AnnoAdvice类
@Aspect
public class AnnoAdvice {
    //切点
    @Pointcut("execution(* service.LoginServiceImpl.*(..))")
    public void pointcut(){

    }
    @Before("pointcut()")
    public void before(){
        System.out.println("before");
    }

    //后置通知 异常不执行
    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("afterReturning");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable{
        System.out.println("around start");
        Object object = point.proceed();
        System.out.println("around end");
        return object;
    }

    @AfterThrowing("pointcut()")
    public void afterException(){
        System.out.println("Exception");
    }

    @After("pointcut()")
    public void after(){
        System.out.println("after");
    }
}

标签:Object,System,loginService,AOP,println,public,out
From: https://www.cnblogs.com/lwx11111/p/17330784.html

相关文章

  • Spring AOP官方文档学习笔记(二)之基于注解的Spring AOP
    1.@Aspect注解(1)@Aspect注解用于声明一个切面类,我们可在该类中来自定义切面,早在Spring之前,AspectJ框架中就已经存在了这么一个注解,而Spring为了提供统一的注解风格,因此采用了和AspectJ框架相同的注解方式,这便是@Aspect注解的由来,换句话说,在Spring想做AOP框架之前,AspectJAOP框......
  • Spring04_Aop
    一、AOP概述(一)AOP简介​ 面向切面编程是一种通过横切关注点(Cross-cuttingConcerns)分离来增强代码模块性的方法,它能够在不修改业务主体代码的情况下,对它添加额外的行为。(二)为何需要AOP​ 面向对象编程OOP可以通过对业务的分析,然后抽象出一系列具有一定属性与行为的类,并通......
  • Spring AOP demo
    动态代理模式实现,比如可以在Bean的生命周期创建阶段,根据Pointcut判断当前bean是否满足切入条件,如果满足,再根据织入器ProxyFactory织入到JoinPoint,再根据bean创建代理对象名词JoinPoint:可以理解成系统中每一个可以应用aop的点,一般是指方法。spring中只支持方法,Pointcut:根据P......
  • Spring04_Aop
    一、AOP概述(一)AOP简介​ 面向切面编程是一种通过横切关注点(Cross-cuttingConcerns)分离来增强代码模块性的方法,它能够在不修改业务主体代码的情况下,对它添加额外的行为。(二)为何需要AOP​ 面向对象编程OOP可以通过对业务的分析,然后抽象出一系列具有一定属性与行为的类,并通......
  • springboot整合阿里云OSS实现多线程下文件上传(aop限制文件大小和类型)
    内容涉及:springboot整合阿里云oss自定义注解及aop的使用:对上传文件格式(视频格式、图片格式)、不同类型文件进行大小限制(视频和图片各自自定义大小)线程池使用:阿里云OSS多线程上传文件阿里云OSS分片上传大文件 业务需求需求一:前端传递单个或多个小文件(这里......
  • 自定义aop
    自定义aopAspectJ应该算的上是Java生态系统中最完整的AOP框架了。SpringAOP和AspectJAOP有什么区别?SpringAOP属于运行时增强,而AspectJ是编译时增强。SpringAOP基于代理(Proxying),而AspectJ基于字节码操作(BytecodeManipulation)。SpringAOP已经集成......
  • AOP底层原理-Cglib动态代理
      publicclassApp{publicstaticvoidmain(String[]args){UserServiceuserService=UserServiceCglibProxy.createUserServiceCglibProxy(UserServiceImpl.class);userService.save();}}publicclassUserServiceCglibProxy{......
  • AOP底层原理-装饰模式(静态代理)
    原始方法:静态代理的方法:   测试:  ......
  • AOP配置(XML)-通知中获取异常对象
     ......
  • AOP配置(XML)-通知中获取参数
        获取参数方式2: ......