• Spring Aop实现简单代码实现


    /*
    * spring的AOP面向切面编程
    * 理解:在不改变原来方法的基础上,实现方法增强处理
    * 实现方式:
    * 1.jdk的Proxy:动态代理,执行的时候处理,要求必须有接口、实现类,代理创建的是实现类的子类。
    * 2.cglib:第三方实现的动态代理,要求必须有父类,代理创建的是父类的子类,比jdk实现的要灵活。
    * AOP中如果有接口则用jkd动态代理,没有则用cglib
    *

    * */

    jdk实现代码:
    代码结构:
    1.目标类:Target
    2.目标接口类:TargetInterface
    3.增强方法类:Advice
    4.用Proxy.newProxyInstance实现对目标类的方法增强
    public class Target implements TargetInterface {
        @Override
        public void save() {
            System.out.println("save run ...");
        }
    }
    public interface TargetInterface {
        void save();
    }
    public class Advice {
        public void before(){
            System.out.println("增强前方法。。。。");
        }
    
        public void after(){
            System.out.println("增强后方法");
        }
    }
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class ProxyText {
        public static void main(String[] args) {
            Target target=new Target();
    
            Advice advice=new Advice();
    
    
            TargetInterface proxyInstance = (TargetInterface)Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    advice.after();
                    Object invoke = method.invoke(target, args);
                    advice.after();
                    return invoke;
                }
            });
    
            proxyInstance.save();
        }
    }
    cglib实现:
    目标类和增强方法一样
    import org.springframework.cglib.proxy.*;
    import java.lang.reflect.Method;
    
    /*
    * spring的AOP面向切面编程
    * 理解:在不改变原来方法的基础上,实现方法增强处理
    * 实现方式:
    * 1.jdk的Proxy:动态代理,执行的时候处理,要求必须有接口、实现类,代理创建的是实现类的子类。
    * 2.cglib:第三方实现的动态代理,要求必须有父类,代理创建的是父类的子类,比jdk实现的要灵活。
    * AOP中如果有接口则用jkd动态代理,没有则用cglib
    *
    * cglib步骤:
    * 1.导入包org.aspectj
    * 2.代码实现,如下。实现代码和Proxy.newProxyInstance差不多
    * */
    public class ProxyTest {
        public static void main(String[] args) {
            //目标对象
            Target target=new Target();
    
            //增强对象
            Advice advice=new Advice();
    
            //1.创建增强器
            Enhancer enhancer=new Enhancer();
            //2.设置父目标
            enhancer.setSuperclass(Target.class);
            //3.设置回调
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    advice.before();
                    Object invoke = method.invoke(target, objects);
                    advice.after();
    
                    return invoke;
                }
            });
            //4.创建代理对象
            Target proxy = (Target) enhancer.create();
            proxy.save();
        }
    }

     spring配置方式实现;

    包配置:

        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.4</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.0.5.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>

    xml方式实现:

    1.target类

    public class Target implements TargetInterface {
    
        @Override
        public void save() {
            System.out.println("save run ...");
        }
    }

    2.接口

    public interface TargetInterface {
        void save();
    }

    3.切面类

    import org.aspectj.lang.ProceedingJoinPoint;
    
    /*
    * aop的重点概念:
            Pointcut(切入点):被增强的方法
            Advice(通知/ 增强):封装增强业务逻辑的方法
            Aspect(切面):切点+通知
            Weaving(织入):将切点与通知结合的过程
    
    *
    *
    *
    * 前置通知        <aop:before>            用于配置前置通知。指定增强的方法在切入点方法之前执行
      后置通知        <aop:after-returning>    用于配置后置通知。指定增强的方法在切入点方法之后执行
      环绕通知        <aop:around>            用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
      异常抛出通知    <aop:throwing>            用于配置异常抛出通知。指定增强的方法在出现异常时执行
      最终通知        <aop:after>                用于配置最终通知。无论增强方式执行是否有异常都会执行
    * */
    public class MyAspect {
        public void before(){
            System.out.println("before增强方法");
        }
    
    
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("around增强前");
            Object proceed = pjp.proceed();
            System.out.println("around增强后");
            return proceed;
        }
    }

    4.配置

    <?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:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation=
                   "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!--目标对象-->
        <bean id="target" class="cn.web.aop.Target"></bean>
    
        <!--切面对象-->
        <bean id="myAspect" class="cn.web.aop.MyAspect"></bean>
    
        <!--配置织入:告诉spring哪些方法需要那总增强-->
        <aop:config>
            <!--声明切面-->
            <aop:aspect ref="myAspect">
                <!--切点表达式-->
                <aop:pointcut id="pointcut" expression="execution( * cn.web.aop.Target.*())"></aop:pointcut>
                <!--切面:切点+通知-->
                <!--<aop:before method="before" pointcut="execution(public void cn.web.aop.Target.save())"></aop:before>-->
                <!--返回值、包、类、方法都可以用通配符取代,表示里面的所有类、方法等-->
                <aop:before method="before" pointcut="execution( * cn.web.aop.Target.*())"></aop:before>
    
                <aop:around method="around" pointcut-ref="pointcut"></aop:around>
            </aop:aspect>
        </aop:config>
    </beans>

    5.测试

    import cn.web.aop.TargetInterface;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class AopTest {
    
        @Autowired
        private TargetInterface target;
    
        @Test
        public void test(){
            target.save();
        }
    }

    注解方式实现;

    就列些不同的

    1.切面类

    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    /*
    * aop的重点概念:
            Pointcut(切入点):被增强的方法
            Advice(通知/ 增强):封装增强业务逻辑的方法
            Aspect(切面):切点+通知
            Weaving(织入):将切点与通知结合的过程
    
    *
    *
    *
    * 前置通知        <aop:before>            用于配置前置通知。指定增强的方法在切入点方法之前执行
      后置通知        <aop:after-returning>    用于配置后置通知。指定增强的方法在切入点方法之后执行
      环绕通知        <aop:around>            用于配置环绕通知。指定增强的方法在切入点方法之前和之后都执行
      异常抛出通知    <aop:throwing>            用于配置异常抛出通知。指定增强的方法在出现异常时执行
      最终通知        <aop:after>                用于配置最终通知。无论增强方式执行是否有异常都会执行
    * */
    @Component
    @Aspect
    public class MyAspect {
    
        @Before("execution(* cn.web.aop.Target.*(..))")
        public void before(){
            System.out.println("before增强方法");
        }
    
    
        @Around("pointcut()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("around增强前");
            Object proceed = pjp.proceed();
            System.out.println("around增强后");
            return proceed;
        }
    
        @AfterReturning("pointcut()")
        public void afterReturning(){
            System.out.println("afterReturning返回后");
        }
    
    
        //设置切点表达式:可以共用
        @Pointcut("execution(* cn.web.aop.Target.*(..))")
        public void pointcut(){
    
        }
    }

    2.配置

    <?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:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    ">
    
        <!--组件扫描-->
        <context:component-scan base-package="com.itheima.anno"/>
    
        <!--aop自动代理-->
        <aop:aspectj-autoproxy/>
    
    </beans>

    3.测试

    import cn.web.anno.TargetInterface;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext_anno.xml")
    public class AnnoTest {
    
        @Autowired
        private TargetInterface target;
    
        @Test
        public void test(){
            target.save();
        }
    }
  • 相关阅读:
    关于python3在centOS7下源码安装的配置
    nginx服务器多虚拟主机配置
    完全数
    高精度计算组合数
    算法竞赛入门经典第六章总结
    线段树
    奶牛
    算法竞赛入门经典第五章总结
    优先队列的使用方法
    放魔法石的游戏
  • 原文地址:https://www.cnblogs.com/zhuyapeng/p/13883311.html
Copyright © 2020-2023  润新知