SpringAOP技术学习(4种技术总结)---Day4

本篇博客知识点

1.AOP的第四种技术:POJO+标签方式实现切面
2.Spring的四种技术总结

AOP的第四种技术:POJO+标签方式实现切面
第四种技术真的非常非常简单!!!
你只要写一个完全独立的类,非常简单的类。
Myadvice

package cn.hncu2.V4;

public class Myadvice {


     public void aa(){ 
         System.out.println("Pojo第四中拦截AOP技术展示");
     }
}

这是你需要拦截的类
Person

/**
 * @author<a href="mailto:953801304@qq.com">胡龙华</a>
 */
public class Person {
    public void run(){
        System.out.println("I'm running!");
    }
    public void Hello(){
        System.out.println("Hello,Spring!");
    }
}

主要核心的就是几个标签
v4.xml 当然你要导spring的包~ 前面讲过

<?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">

    <bean id="muadice" class="cn.hncu2.V4.Myadvice"></bean>
    <aop:config>
        <aop:aspect ref="muadice">
        <aop:before method="aa" pointcut="execution( void cn..Person.*(..) )"/>
        </aop:aspect>
    </aop:config>

    <bean id="p" class="cn.hncu2.V4.Person"></bean>
</beans>

下面是测试代码和结果
这里写图片描述

第一种技术:最底层的方式实现AOP技术拦截,纯Java方式和XML方式

/**
     * @author<a href="mailto:953801304@qq.com">胡龙华</a>
     */
    @Test
    public void t1(){
        //切面=切点+通知  Advisor = cut + advice
        // 1.创建一个原型对象   
        Person p = new Person();
        // 2.实现代理类工厂    
        ProxyFactoryBean factory = new ProxyFactoryBean();
        //3.实现原型对象,代理目标
        factory.setTarget(p);
        //4.声明切点:就是说你要来拦截原型对象的哪些方法
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        //5.设置切点的正则:用正则表达式来设置拦截所有带run的方法
        pointcut.setPattern(".*run.*");
        //6.定义通知: 设定方法执行前栏、还是后栏还是都拦截(环绕栏)
        Advice advice = new MethodInterceptor() {
            //环绕栏
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("前面拦拦");
                Object obj = invocation.proceed();
                System.out.println("后面拦截");
                return obj;
            }
        };
        //7.声明切面  :  Advisor = pointcut + advice
        Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
        //8.把切面设置到代理工厂里:进厂子干活
        factory.addAdvisor(advisor);
        //9.代理工厂生产代理后的对象
        Person p2 = (Person) factory.getObject();
        //测试
        p2.run();
        p2.Hello();

对于的XML方式—可以简化

 <!--  1.创建一个原型对象-->
        <bean id="p" class="cn.hncu2.v1.Person"/>
        <!--  2.实现代理类工厂  -->
        <bean id="factory" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!--  3.实现原型对象,代理目标 -->
            <property name="target" ref="p"/>
        <!--  8.把切面设置到代理工厂里:进厂子干活 -->
            <property name="interceptorNames">
                <list> <value>advisor</value> </list>
            </property>
        </bean>
        <!--  4.声明切点:就是说你要来拦截原型对象的哪些方法 -->
        <bean id="pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
        <!--  5.设置切点的正则:用正则表达式来设置拦截所有带run的方法 -->
            <property name="pattern" value=".*run.*"/>
        </bean>
        <!--  6.定义通知: 设定方法执行前栏、还是后栏还是都拦截(环绕栏) -->
        <!--  因为Java是实习的是匿名内部类,那么我们就自己写一个类就好了 -->
        <bean id="advice" class="cn.hncu2.v1.AroundAdvice"/>
        <!--  7.声明切面  :  Advisor = pointcut + advice-->
        <bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
            <property name="pointcut" ref="pointcut"/>
            <property name="advice" ref="advice"></property>
        </bean>

第二种技术:核心与第一种相比是加入了切点语言,把拦截做得强大
纯Java方式底层代码

Person p = new Person();

        ProxyFactoryBean factory = new ProxyFactoryBean();

        factory.setTarget(p);

        AspectJExpressionPointcut cut = new AspectJExpressionPointcut();

        cut.setExpression("execution( void cn.hncu2.v2.Person.run() )");

        // 设置切点的表达式---切点语言
//      cut.setExpression("execution( void cn.hncu.v2.Person.run() )"); // 写死的
        Advice advice = new MethodInterceptor() {

            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("---------");
                Object obj = invocation.proceed();
                System.out.println("---------");
                return obj;
            }
        };
        Advisor advisor = new DefaultPointcutAdvisor(cut,advice);
        factory.addAdvisor(advisor);

        Person p2 = (Person) factory.getObject();
        p2.run();
        p2.Hello();

也可以用XML 方式实现,更简洁

<!-- 自动代理 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

    <bean id="advisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
        <property name="expression" value="execution(void cn.hncu2.v2.Person.run() )"/>
        <property name="advice">
            <bean class="cn.hncu2.v2.AroundAdvice"></bean>
        </property>
    </bean>

    <bean id="p" class="cn.hncu2.v2.Person"></bean>

第三种技术:核心思想和前面两是一样的都是 实现切面=切点+通知这个公式,区别在于他是通过注解+XML的方式实现
一个通过注解实现的切面

package cn.hncu2.v3;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
// 公式: 切面 = 切点 + 通知
@Aspect  // 类名字前加@Aspect
public class Myadvice {
//切点的两种形式   
     //第一种形式: 把用字符表示切点---放在成员变量上
    private final String Cut ="execution( * cn..Person.*(..) ) )"; 
    //第二种形式: 注释@Poincut---放在成员方法上
     @Pointcut(value="execution( * cn..Person.*(..) )")  //@Pointcut中的value属性来指定切点的表达式----用aspectj切点语言
     public void aa(){ //该方法没别的功能,就是为了让@Pointcut有个寄居的地方,同时也用于标识该注解
     }

     @Before(Cut) // before通知+第一种形式切点
        public void before1(){
            System.out.println("@Before拦截");
    }
//通知:必须加载函数方法名字上面, 参数JoinPoint jp 可选  (@Around为必选)
    @Before(value = "aa()")// before通知+第二种形式切点
    public void before2(){
        System.out.println("@Before方法拦截");
    }

    @After(value = "aa()")// After通知+第二种形式切点
    public void After2(){
        System.out.println("@After拦截");
    }

    @Around(value = "aa()")// After通知+第一种形式切点
    public Object Around1(ProceedingJoinPoint p) throws Throwable{
        System.out.println("@Around前拦截");
        Object res = p.proceed(); //放行
        System.out.println("@Around后拦截");
        return res;
    }

    @AfterReturning(value = "aa()")
    public void AfterReturning(){
        System.out.println("函数正常返回未出异常时执行");
    }

    @AfterThrowing(value = "aa()")
    public void AfterThrowing(){
        System.out.println("函数出现异常时候执行");
    }
}

添加到bean容器就可以使用了

<!-- 自动代理的标签 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <!-- 注解式前面 -->
    <!-- <bean class="cn.hncu2.v3.Myadvice"></bean> -->
    <bean class="cn.hncu2.v3.Myadvice2"></bean>

    <bean id="p" class="cn.hncu2.v3.Person"></bean>

第四种技术:是通过存标签方式实现 核心也是切面=切点+通知

一个简单的类

public class Myadvice {
    /**
     * @author<a href="mailto:953801304@qq.com">胡龙华</a>
     */
     public void aa(){ 
         System.out.println("Pojo第四中拦截AOP技术展示");
     }
}

把前面那个类的方式 用作切面

<bean id="muadice" class="cn.hncu2.V4.Myadvice"></bean>
    <aop:config>
        <aop:aspect ref="muadice">
        <aop:before method="aa" pointcut="execution( void cn..Person.*(..) )"/>
        </aop:aspect>
    </aop:config>

    <bean id="p" class="cn.hncu2.V4.Person"></bean>

四种技术是从第一种慢慢演变的第四种的,我学习的时候是从第一种开始学,更好的理解他里面的思想,用的话用第四种会更加轻松,简单

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值