假设在在一个业务组件接口中有三个核心关注点business1、business2、business3。
我们需要在这些关注点执行之前验证用户、开启事务,在这些关注点执行之后关闭事务、写入日志等。此时我们可以使用Spring aop来实现这些功能。其中验证用户、开启事务、关闭事务以及写入日志等属于横切关注点或者交叉关注点。
业务组件接口Component:
package com.newland.aop;
public interface Component {
public void business1();
public void business2();
public void business3();
}
业务组件接口实现类ComponentImpl:
package com.newland.aop.impl;
public class ComponentImpl implements com.newland.aop.Component {
@Override
public void business1() {
System.out.println("执行业务方法business1...");
}
@Override
public void business2() {
System.out.println("执行业务方法business2...");
}
@Override
public void business3() {
System.out.println("执行业务方法business3...");
}
}
⑴使用基于Schema的配置文件配置Spring Aop
定义一个处于横切交叉点关注点的切面模块AspectBean,代码如下:
package com.newland.aop;
public class AspectBean {
public void validateUser()
{
System.out.println("正在验证用户...");
}
public void beginTransaction()
{
System.out.println("开启事务...");
}
public void endTransaction()
{
System.out.println("结束事务...");
}
public void writeLog()
{
System.out.println("书写日志...");
}
}
有了处理横切交叉问题的切面模块Bean,下面我们就可以在Spring的配置文件中进行Spring Aop相关配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<aop:config>
<aop:aspect id="aspectDemo" ref="aspectBean">
<aop:pointcut id="somePointCut" expression="execution(* com.newland.aop.Component.business*())"/>
<aop:before method="validateUser" pointcut-ref="somePointCut"/>
<aop:before method="beginTransaction" pointcut-ref="somePointCut"/>
<aop:after method="endTransaction" pointcut-ref="somePointCut"/>
<aop:after method="writeLog" pointcut-ref="somePointCut"/>
</aop:aspect>
</aop:config>
<bean id="aspectBean" class="com.newland.aop.AspectBean"></bean>
<bean id="component" class="com.newland.aop.impl.ComponentImpl"></bean>
</beans>
⑵使用基于注解配置使用Spring Aop
首先写一个包含使用了Java注解来标识切面相关信息的Bean,方法的名称及内容跟上面的AspectBean的完全一样,代码如下:
package com.newland.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AspectAnnotationBean {
@Pointcut("execution(* com.newland.aop.Component.business*())")
public void somePointCut()
{
}
@Around("somePointCut()")
public void validateUser(ProceedingJoinPoint proceed) throws Throwable
{
System.out.println("正在验证用户...");
proceed.proceed();
System.out.println("验证用户完成...");
}
@Before("somePointCut()")
public void beginTransaction()
{
System.out.println("开启事务...");
}
@After("somePointCut()")
public void endTransaction()
{
System.out.println("结束事务...");
}
@After("somePointCut()")
public void writeLog()
{
System.out.println("书写日志...");
}
}
修改Spring的配置文件ApplicationContext.xml,修改后的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<aop:aspectj-autoproxy/>
<bean id="aspectBean" class="com.newland.aop.AspectAnnotationBean"></bean>
<bean id="component" class="com.newland.aop.impl.ComponentImpl"></bean>
</beans>
⑶基于API方式来使用Spring Aop
在上面的两种实现方式中,都需要使用到AspectJ的aspectjweaver.jar来帮助我们解析切入点相关表达式。如果我们不想使用AspectJ,仅仅依靠Spring Aop方面的API也可以实现类似的功能。
首先写一个用来具体处理连接点的通知Bean,这个Bean实现了MethodBeforeAdvice及AfterReturnAdvice接口。AdviceBean代码如下:
package com.newland.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
public class AdviceBean implements MethodBeforeAdvice, AfterReturningAdvice {
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
validateUser();
beginTransaction();
}
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
endTransaction();
writeLog();
}
public void validateUser()
{
System.out.println("正在验证用户...");
}
public void beginTransaction()
{
System.out.println("开启事务...");
}
public void endTransaction()
{
System.out.println("结束事务...");
}
public void writeLog()
{
System.out.println("书写日志...");
}
}
有了通知处理的类AdviceBean,还要进一步定义切入点以及切面模块,这里我们直接使用Spring自带的切入点处理实现NameMatchPointcut以及默认切面封装(Spring中称为通知器)DefaultPointcutAdvisor类来实现。因此,不需要再书写自己的切入点以及切面类,直接使用上面的两个类在配置文件中配置即可。Applicationcontext.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="adviceBean" class="com.newland.aop.AdviceBean"></bean>
<bean id="targetBean" class="com.newland.aop.impl.ComponentImpl"></bean>
<bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut">
<property name="mappedName" value="business*"></property>
</bean>
<bean id="aspectBean" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="adviceBean"></property>
<property name="pointcut" ref="pointcutBean"></property>
</bean>
<bean id="component" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="targetBean"></property>
<property name="interceptorNames">
<list>
<value>aspectBean</value>
</list>
</property>
</bean>
</beans>
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yby0260/archive/2010/08/09/5799727.aspx