• AOP切面编程


     

    1.JDK动态代理方式实现

    public static UserService createService(){
        //目标类
        final UserService userService = new UserServiceImp();
        //切面类
        final MyAspect myAspect = new MyAspect();
        /**
         * 代理类:
         * class Proxy{
         *     public void addUser(){
         *         invoke(this,addUser,args)
         *     }
         *     public void deleteUser(){
         *         invoke(this,addUser,args)
         *     }
         * }
         *
         * classLoader:类加载器,动态代理类在运行时创建,任何类都需要类加载器将其加载到内存。
         *      一般使用当前类的类加载器
         *  interfaces:代理类需要实现的所有接口
         *      方式1:userService.getClass().getInterfaces()
         *      方式2:new Class[]{UserService.class}
         *  InvocationHandler:处理类,接口,匿名内部类
         *      invoke方法,代理类的每个方法执行时,都会调用一次该方法
         *          proxy:代理对象
         *          method:代理对象执行的方法的描述对象
         *          args:方法参数
         */
    
        UserService proxyService = (UserService) Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(),
                userService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
                        myAspect.before();
                        Object obj = method.invoke(userService,args);
                        myAspect.after();
                        return obj ;
                    }
                });
        return proxyService;
    }

    2.采用字节码增强的框架,在运行时创建目标类的子类,从而实现增强

    2.1 导入jar包

    核心:hibernatelibytecodecglibcglib-2.2.jar

    依赖:struts2.3.15.4struts-2.3.15.3libasm-3.3.jar

    spring-core...jar已经整合了这两个jar包

    3. AOP联盟通知类型

    AOP联盟为通知定义了org.aopalliance.aop.Advice

     环绕通知,必须手动执行目标方法

    try{

    //前置通知

    //执行目标方法

    //后置通知

    }catch(){}

    4. spring编写代理:半自动

    4.1  让spring去创建代理对象,从spring容器手动获取代理对象

      导入jar包:4+1

        AOP jar包:AOP联盟(规范)spring-framework-3.0.2.RELEASE-dependenciesorg.aopalliancecom.springsource.org.aopalliance1.0.0com.springsource.org.aopalliance-1.0.0.jar

        spring-aop(实现)spring-framework-3.2.0.RELEASElibsspring-aop-3.2.0.RELEASE.jar

    <!-- bean definitions here
        创建目标类
    -->
    <bean id="userService" class="c_proxy_factoryBean.UserServiceImp"></bean>
    <bean id="myAspect" class="c_proxy_factoryBean.MyAspect"></bean>
    <!-- 使用spring的工厂bean,返回代理对象 -->
    <bean id="proxyUserService" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 设置接口
        确定接口,是个数组,使用array设置,如果只有一个值时,可以使用value配置 -->
        <property name="interfaces">
            <array>
                <value>c_proxy_factoryBean.UserService</value>
            </array>
        </property>
        <!--设置目标类-->
        <property name="target" ref="userService"></property>
        <!--  设置通知
        是个String数组,使用array设置,如果只有一个值时,可以使用value配置 -->
        <property name="interceptorNames" value="myAspect"></property>
        <!--强制使用cglib-->
        <property name="optimize" value="true"></property>
    </bean>

    底层机制:

      如果没有设置接口,则使用cglib方式

      如果设置接口,默认使用JDK代理方式

      可以强制使用cglib方式

    5.spring AOP编程,全自动

       从spring容器中正常获取目标类,如果配置了AOP,spring自动生成代理类

      必须确定目标类,支持aspectJ切入点表达式,导入jar包spring-framework-3.0.2.RELEASE-dependenciesorg.aspectjcom.springsource.org.aspectj.weaver1.6.8.RELEASEcom.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

       目标类-->pointcut(切入点) + 通知(advicor)--》advicor(切面)

     excution() || excution()

    public class MyAspect implements MethodInterceptor{
        @Override
        public Object invoke(MethodInvocation methodInvocation) throws Throwable {
            System.out.println("before method...");
            Object obj = methodInvocation.proceed();
            System.out.println("after method...");
            return obj;
        }
    }
    <!-- bean definitions here
        创建目标类  -->
    <bean id="userService" class="d_springAop.UserServiceImp"></bean>
    <bean id="bookService" class="d_springAop.BookService"></bean>
    <bean id="myAspect" class="d_springAop.MyAspect"></bean>
    <!--spring AOP,导入命名空间,是否使用cglib-->
    <aop:config proxy-target-class="true">
        <!--
            pointcut:切入点,目标类的方法
            advicor:特殊的切面,只有一个通知和一个切入点,组织切入点和通知(增强)
        -->
        <!--切入点表达式-->
        <aop:pointcut id="myPointcut" expression="execution(* d_springAop.*.*(..))" />
        <aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut" />
    </aop:config>

    6. aspectJ

     6.1 介绍

      aspectJ是基于java的AOP框架

      spring2.0后支持AspectJ切入点表达式

      用途:自定义开发,代码植入

    6.2 基于xml

    6.3 基于注解

  • 相关阅读:
    使用helm管理复杂kubernetes应用
    helm repository 相关
    PSQLException: An I/O error occurred while sending to the backend.
    使用helm进行kubernetes包管理
    Slave作为其它Slave的Master时使用
    ext3是对ext2文件系统的一个扩展高性能日志文件系统
    ready是先执行的,load后执行,DOM文档的加载步骤
    jQuery上定义插件并重设插件构造函数
    在PHP与HTML混合输入的页面或者模板中就需要对PHP代码进行闭合
    decode 函数将字符串从某种编码转为 unicode 字符
  • 原文地址:https://www.cnblogs.com/zhuxiang1633/p/8504514.html
Copyright © 2020-2023  润新知