Spring之AOP学习小结

在学习aop之前先来解释一下aop一些概念
[list]
[*]Joinpoint:它定义在哪里加入你的逻辑功能,对于Spring AOP,Jointpoint指的就是Method。
[*]Advice:特定的Jointpoint处运行的代码,对于Spring AOP 来讲,有Before advice、AfterreturningAdvice、ThrowAdvice、AroundAdvice(MethodInteceptor)等。
[*]Pointcut:一组Joinpoint,就是说一个Advice可能在多个地方织入,
[*]Aspect:实际是Advice和Pointcut的组合,但是Spring AOP 中的Advisor也是这样一个东西,但是Spring中为什么叫Advisor而不叫做Aspect。
[*]Target:被通知的对象。
[*]Proxy:将通知应用到目标对象后创建的对象
[*]Weaving:将Aspect加入到程序代码的过程,对于Spring AOP,由ProxyFactory或者ProxyFactoryBean负责织入动作。
[/list]

spring对AOP的支持有以下4种情况:
[list]
[*]经典的基于代理的aop(各版本spring)
[*]@AspectJ注解驱动的切面(spring2.0后)
[*]纯pojo切面(spring2.0后)
[*]注入式AspectJ切面(各版本spring)
[/list]

ITarget.java
package com.myspring.aop;

public interface ITarget {
public void execute() throws TargetException;
}


TargetImpl.java
package com.myspring.aop;

public class TargetImpl implements ITarget {

public TargetImpl() {
}

public void execute() throws TargetException {
System.out.println("main...");
}
}


创建通知
Advice .java
package com.myspring.aop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

public class Advice implements MethodBeforeAdvice,
AfterReturningAdvice, ThrowsAdvice {

public Advice() {}

public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("传统经典aop的before...");
}

public void afterReturning(Object rtn, Method method,
Object[] args, Object target) throws Throwable {
System.out.println("传统经典aop的afterReturning...");
}

public void afterThrowing(Throwable throwable) {
System.out.println("传统经典aop的afterThrowing...");
}

public void afterThrowing(Method method, Object[] args, Object target,
Throwable throwable) {
System.out.println("传统经典aop的afterThrowing2...");
}

}


TargetException .java
package com.myspring.aop;

@SuppressWarnings("serial")
public class TargetException extends RuntimeException {
public TargetException() {}

public TargetException(String message) {
super(message);
}
}


使用自动代理@AspectJ切面时,需要先注册一个切面AspectAdvice.java
package com.myspring.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect//声明切面
public class AspectAdvice {

@Pointcut("execution(* *.execute(..))")//定义切点,匹配规则为(返回类型 返回类.方法(参数设置)
public void todo(){}

@Before("todo()")
public void before() {
System.out.println("自动代理@AspectJ切面before...");
}

@AfterReturning("todo()")
public void afterReturning() {
System.out.println("自动代理@AspectJ切面afterReturning...");
}

@AfterThrowing("todo()")
public void afterThrowing() {
System.out.println("自动代理@AspectJ切面afterThrowing...");
}

}

AdviceBean.java
package com.myspring.aop;

public class AdviceBean {

public void before() {
System.out.println("纯POJO切面before...");
}

public void afterReturning() {
System.out.println("纯POJO切面afterReturning...");
}

public void afterThrowing() {
System.out.println("纯POJO切面afterThrowing...");
}
}



applicationContext.xml
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<!-- 当定义一个纯粹的POJO切面时,创建此Bean -->
<bean id="adviceBean" class="com.myspring.aop.AdviceBean"></bean>
<!-- 利用spring AOP的配置元素定义一个通知 -->
<aop:config>
<!-- 引用刚才定义的一个纯粹的POJO切面Bean -->
<aop:aspect ref="adviceBean">
<!-- 定义一个命名切点,必点切点定义的重复,expression用于配置匹配规则,(返回类型 返回类.方法(参数设置) -->
<aop:pointcut id="todo" expression="execution(* com.myspring.aop.TargetImpl.execute(..))" />
<!-- 方法前通知 -->
<aop:before method="before" pointcut-ref="todo" />
<aop:after-returning method="afterReturning" pointcut-ref="todo" />
<aop:after-throwing method="afterThrowing" pointcut-ref="todo"/>
</aop:aspect>
</aop:config>

<!-- ************************************** -->
<bean id="aspectAdvice" class="com.myspring.aop.AspectAdvice"></bean>
<!-- 当使用自动代理@AspectJ切面时,需要定义自动配置元素,在原来的xml文件的beans中加入xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd,具体位置如上 -->
<aop:aspectj-autoprox />

<!-- ************************************** -->
<!-- 以下为传统的aop代理 -->
<!-- 定义一个bean -->
<bean id="target" class="com.myspring.aop.TargetImpl">
</bean>

<!-- 定义一个通知bean -->
<bean id="advice" class="com.myspring.aop.Advice">
</bean>

<!-- 正则表达式切入点 -->
<bean id="jdkRegexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="advice" />
<property name="pattern" value=".*execute" />
</bean>

<!-- AspectJ切点 -->
<bean id="aspectjPointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="advice" ref="advice" /> <property name="expression"
value="execution(* *.execute(..))" /> </bean>
<!-- 使用ProxyFactoryBean工厂,用于生成一个代理,把一个或多个拦截者(和通知者)应用到Bean -->
<bean id="myAop" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target" />
<property name="proxyInterfaces" value="com.myspring.aop.ITarget" />
<property name="interceptorNames" value="jdkRegexpAdvisor" />
</bean>

<!-- 创建自动代理,会自动检查通知者的切点是否匹配bean的方法,并且使用通知的代理来替换这个bean定义 -->
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>


TestSpringAop.java
package com.myspring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpringAop {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//使用经典的aop
ITarget target = (ITarget) ctx.getBean("myAop");
//使用自动代理,可以直接调用目标对象
ITarget autotarget = (ITarget) ctx.getBean("target");
target.execute();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值