您的位置:首页 > 编程语言 > Java开发

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

2017-08-23 11:07 375 查看

本篇博客知识点

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>


四种技术是从第一种慢慢演变的第四种的,我学习的时候是从第一种开始学,更好的理解他里面的思想,用的话用第四种会更加轻松,简单
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  技术 class aop