• AOP


    切面编程,实现切面插入,让代码更加灵活。

    1.继承实现

    新建一个接口:

    public interface UserService {
        public abstract void syso();
        
    }

    来个实现类,

    public class ExtendAOP extends UserServiceImpl {
        
        /** 通过继承方式实现aop切面插入。
         *  缺点:只能单继承。
         */
        @Override
        public void syso() {
            System.out.println("开始切入");
            super.syso();
            System.out.println("切入完毕");
        }
        
    }

    测试:

    @org.junit.Test
        public void test(){
            ExtendAOP aop=new ExtendAOP();
            aop.syso();
        }

    结果:

    开始切入
    打印日志
    切入完毕

    2.静态代理模式,接口加多一个方法。

    public interface UserService {
        public abstract void print();
        public void syso();
    
    }

    实现:

    public class Proxy implements UserService {
        /**
         * 静态代理,通过实现接口的方式,但是同样要创建实例,没有动态代理。
         */
        UserServiceImpl userServiceImpl = new UserServiceImpl();
        @Override
        public void print() {
            
        }
        @Override
        public void syso() {
            System.out.println("开始切入");
            userServiceImpl.syso();
            System.out.println("切入完毕");
        }
    }

    测试:

    @org.junit.Test
        public void proxy(){
            Proxy proxy=new Proxy();
            proxy.syso();
        }

    结果:

    开始切入
    打印日志
    切入完毕

    3.使用sping框架提供的aop插入功能,使用配置文件配置。

    jar包

    image

    同样还是接口和接口的实现。…

    配置文件加上

    <!-- AOP配置文件写法 -->
              <bean id="logger" class="logger.Logger"></bean>
              <aop:config>
                  <aop:pointcut expression="execution (* service.impl.User*.*(..))" id="aop"/><!-- 返回值 service.impl包下任意java,任意方法  参数随意  -->
                  <aop:aspect ref="logger">
                      <aop:before method="before" pointcut-ref="aop"/>
                      <aop:after method="after" pointcut-ref="aop"/>
                      <aop:around method="logAround" pointcut-ref="aop"/>
                      <aop:after-returning method="afterReturning" pointcut-ref="aop"/>
                  </aop:aspect>
              </aop:config>

    其中bean 对应着相应的插入的类路径 ,aop:point 表示插入点,后面的表达式匹配要插入的地方。 aop:aspect插入面,对应着插入类,下面就是各个对应的方法该插入到那里。(注:这里是关键的配置,其他的没加上来。单元测试还要有获得对象的bean或者注解扫描包的配置。)

    插入的实现类:Logger

    public class Logger {
        public static void print(){
            System.out.println("打印日志");
        }
        public static void before(){
            System.out.println("-----before------");
        }
        public static void after(){
            System.out.println("-----after------");
        }
        /** 环绕 通知 */
        public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("---前--环绕日志--------");
            Object ret = pjp.proceed();// 执行目标方法相当于InvocationHandler
            System.out.println("---后--环绕日志--------");
            return ret;
        }
        public static void afterReturning(){
            System.out.println("-----after-returning------");
        }
    
    }

    测试:

    @org.junit.Test
        public void Aop(){
            ApplicationContext context=new ClassPathXmlApplicationContext("application4.xml");
            UserService service= (UserService) context.getBean("userServiceImpl");
            service.syso();
        }

    结果:(xml注释after、logAround、afterReturning)

    -----before------
    打印日志

    4.用AOP注解了实现。

    插入实现类:

    @Aspect
    @Component
    public class LoggerByAnnotation {
        
        @Pointcut("execution(* service.impl.UserService2Impl.*(..))")
        private void anyMethod(){}
        
        @Before("
    anyMethod()
    ")
        public static void before(){
            System.out.println("-----before------");
        }
        @After("
    anyMethod()
    ")
        public static void after(){
            System.out.println("-----after------");
        }
        /** 环绕 通知 */
        @Around("
    anyMethod()
    ")
        public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("----前--环绕日志--------");
            Object ret = pjp.proceed();// 执行目标方法相当于InvocationHandler
            System.out.println("----后--环绕日志--------");
            return ret;
        }
         @AfterReturning("
    anyMethod()
    ")
        public static void afterReturning(){
            System.out.println("-----after-returning------");
        }
        public static void print() {
            System.out.println("gggggg");
        }
    
    }

    配置文件:

    <!-- Aop注解的方式 -->
              <!-- AOP插入的类也要扫描一波 -->
              <context:component-scan base-package="logger"></context:component-scan>
              <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"></aop:aspectj-autoproxy>
              <!--  CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,
                      所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,
                      对于final方法,无法进行代理  -->

    注意:pring中的切面类固然要用@Aspect标注,但也不要忘了用@Componet标注,这样才能被注册到容器中。

    测试:

    @org.junit.Test
        public void Aop(){
            ApplicationContext context=new ClassPathXmlApplicationContext("application4.xml");
            UserService2 service= (UserService2) context.getBean("userService2Impl");
            service.save();
        }

    结果:

    -----before------
    打印日志

  • 相关阅读:
    VueJS中学习使用Vuex详解
    https://www.cnblogs.com/chinabin1993/p/9848720.html
    5分钟带你入门vuex(vue状态管理)
    引用第三方 chalk 模块
    Vue-Grid-Layout分享一款好用的可拖拽组件
    vue-grid-layout
    拖拽 ‘vue-grid-layout’ 插件了解下
    Vue国际化处理 vue-i18n 以及项目自动切换中英文
    Java线程池ThreadPoolExecutor使用和分析(三)
    Java线程池ThreadPoolExecutor使用和分析(二)
  • 原文地址:https://www.cnblogs.com/lq625424841/p/7520954.html
Copyright © 2020-2023  润新知