当前位置:首页 > 阅读 > Spring框架 spring-aop (spring框架的优点)

Spring框架 spring-aop (spring框架的优点)

Spring框架 spring-aop (spring框架的优点)

1.Spring中的aop

Aop是面向切面的编程思想,在Spring框架中的Spring-aop.jar模块提供了aop的支持,但它并不是一个完整的AOP解决方案。

AspectJ是基于java语言的AOP框架,它定义了AOP的语法,使用专门的编译器生成符合JAVA编码规范的字节码。

2.增强类型(通知)

AOP的实现无论采用代理还是预编译式织入,都是为了增强目标代码的功能。

3.SpringAop

springAop使用动态代理的方式实现AOP,动态代理的实现可采用JDK动态代理或CGLIB的方式。JDK动态代理是基于接口,CGLIB不能代理final类。所以采用springAop方式时,要注意被代理的对象要么实现了某接口,也不能是final类。

3.1.实现流程

1.编写增强类

/**

* MethodBeforeAdvice:前置通知接口

* MethodInterceptor:环绕通知接口

* AfterReturingAdvice:后置通知接口

*/

publicclass SpringAopAspect implements

//AfterReturningAdvice, MethodBeforeAdvice,

MethodInterceptor

{

private Logger logger =LoggerFactory.getLogger(SpringAopAspect.class);

//环绕增强方法

@Override

public Object invoke(MethodInvocationmethodInvocation) throws Throwable {

Object ret=null;

try{

logger.debug(springAopAspect-before【前置通知】,正在增强:+methodInvocation.getMethod().getName()+方法);

ret =methodInvocation.proceed();//执行下一个方法

logger.debug(springAopAspect-afterReturning【后置通知】,正在增强:+methodInvocation.getMethod().getName()+方法);

}catch (Exception o){

logger.debug(springAopAspect-exception【异常通知】,正在增强:+methodInvocation.getMethod().getName()+方法);

logger.debug(异常信息:+o.getMessage());

}finally {

logger.debug(springAopAspect-return【最终通知】,正在增强:+methodInvocation.getMethod().getName()+方法);

}

return ret;

}

//前置增强回调方法

/* @Override

public void before(Method method,//目标方法对象

Object[]objects,//方法参数

Object o) throwsThrowable {

logger.debug(springAopAspect-before【前置通知】,正在增强:+method.getName()+方法,所带的参数为:+objects);

}*/

//后置增强回调方法

/*@Override

public void afterReturning(Objecto,

Methodmethod,

Object[]objects,

Objecto1) throws Throwable {

logger.debug(springAopAspect-afterReturning【后置通知】,正在增强:+method.getName()+方法,返回值:+o);

}*/

}

2.配置bean

!--被代理的bean--

bean id=userServiceBean

lazy-init=false class=org.fjh.service.impl.UserServiceBean

/bean

!--增强bean--

bean id=springAopAspectBean class=org.fjh.aop.SpringAopAspect/

3.配置增强代理bean,和代理对象的生成bean

!--增强者bean(切入点)--

bean id=aspectBean class=org.springframework.aop.support.RegexpMethodPointcutAdvisor

!--使用正则表达式,指定增强(通知)的规则--

property name=pattern

value=org\.fjh\.service\.impl\..*/

!--增强处理器--

property name=advice

ref bean=springAopAspectBean/

/property

/bean

!--使用proxyFactoryBean生成代理对象--

bean id=userServiceproxyBean class=org.springframework.aop.framework.ProxyFactoryBean

!--指定接口--

property name=interfaces

valueorg.fjh.service.IUserServiceBean/value

/property

!--指定被代理的对象--

property name=target ref=userServiceBean /

!--指定切入点--

property name=interceptorNames

valueaspectBean/value

/property

/bean

4.取得代理bean

@Test

public void springAopTest(){

//取得代理后的bean

IUserServiceBean bean= (IUserServiceBean)ctx.getBean(userServiceproxyBean);

bean.updateUser();

}

4.AspectJ

可使用xml和注解方式都可实现aop

4.1.Xml的方式4.1.1.实现步骤

1.引入aspectJ的依赖

在pom.xml中加入

!--

dependency

groupIdorg.aspectj/groupId

artifactIdaspectjrt/artifactId

version1.9.4/version

/dependency

!--

dependency

groupIdorg.aspectj/groupId

artifactIdaspectjweaver/artifactId

version1.9.4/version

/dependency

2.编写切面类

public class AspectJAspect {

private Logger logger = LoggerFactory.getLogger(AspectJAspect.class);

//实现5个增强通知的方法

private void beforeHandler(JoinPoint jp){

Stringname=jp.getTarget().getClass().getSimpleName();

StringmethodName=jp.getSignature().getName();

Object args = jp.getArgs();

String str=被增加的类型:+name+,增加的方法名:+methodName+,参数:+args;

logger.debug(AspectJAspect--【前置通知】:+str);

}

private void afterHandler(JoinPoint jp){

logger.debug(AspectJAspect--【最终通知】:增加的方法名:+jp.getSignature().getName());

}

private void afteringHandler(JoinPoint jp,Objectret){

logger.debug(AspectJAspect--【后置通知】:增强的方法名:+jp.getSignature().getName()+,返回值:+ret);

}

private void exceptionHandler(JoinPoint jp,Exceptionex){

logger.debug(AspectJAspect--【异常通知】:增强的方法名:+jp.getSignature().getName());

logger.debug(AspectJAspect--【异常信息】:+ex.getMessage());

}

private Object around(ProceedingJoinPoint pjp)throws Throwable{

Object ret = pjp.proceed();//调用下一个方法

logger.debug(AspectJAspect--【环绕通知】:+pjp.getSignature().getName());

return ret;

}

}

3.加入aop的命名空间

在applicationContext.xml中加入aop的命名空间

?xml version=1.0 encoding=UTF-8?

beans xmlns=

xmlns:xsi=

xmlns:aop=

xsi:schemaLocation=

4.配置aop

!--aspectJ切面类--

bean id=aspectJaspectBeanclass=org.fjh.aop.AspectJAspect/

!--配置aop--

aop:config

!--定义切入点--

aop:pointcut id=mypointcut expression=execution(* org.fjh.service..*(..)) /

!--增强切面

ref:引用以定义的切面类bean--

aop:aspect ref=aspectJaspectBean

!--

method:切面中处理方法

pointcut:切入点规则

pointcut-ref:引用以定义的规则

--

aop:before method=beforeHandler pointcut-ref=mypointcut/

aop:around method=around pointcut-ref=mypointcut/

!--

returning:返回方法的参数名称(用于接收目标方法返回值)

--

aop:after-returning method=afteringHandler pointcut-ref=mypointcut returning=ret/

!--

throwing:异常处理方法的参数名称(用于接收目标方法执行过程抛出的异常)

--

aop:after-throwing method=exceptionHandler pointcut-ref=mypointcut throwing=ex /

aop:after method=afterHandler pointcut-ref=mypointcut/

/aop:aspect

/aop:config

/beans

5.取得bean

@Test

public void aspectJTest()

{

IUserServiceBean bean =(IUserServiceBean) ctx.getBean(userServiceBean);

bean.addUser(rose);

}

4.2.注解方式4.2.1.实现步骤

1.引入aspectJ的依赖

!--

dependency

groupIdorg.aspectj/groupId

artifactIdaspectjrt/artifactId

version1.9.4/version

/dependency

!--

dependency

groupIdorg.aspectj/groupId

artifactIdaspectjweaver/artifactId

version1.9.4/version

/dependency

2.编写aspect处理类

@Aspect //告诉spring此类是一个切面类

@Component//标识本类是个组件

publicclass AspectJAspectAno {

private Logger logger = LoggerFactory.getLogger(AspectJAspectAno.class);

//定义切入点

@Pointcut(execution(*org.fjh.service..*(..)))

private void mypointcut(){}

//实现5个增强通知的方法

//mypointcut()是以定义的切入点

@Before(value = mypointcut())

private void beforeHandler(JoinPoint jp){

Stringname=jp.getTarget().getClass().getSimpleName();

StringmethodName=jp.getSignature().getName();

Object args = jp.getArgs();

String str=被增加的类型:+name+,增加的方法名:+methodName+,参数:+args;

logger.debug(AspectJAspectAno--【前置通知】:+str);

}

@After(value = mypointcut())

private void afterHandler(JoinPoint jp){

logger.debug(AspectJAspectAno--【最终通知】:增加的方法名:+jp.getSignature().getName());

}

@AfterReturning(value = mypointcut(), returning = ret)

private void afteringHandler(JoinPoint jp,Objectret){

logger.debug(AspectJAspectAno--【后置通知】:增强的方法名:+jp.getSignature().getName()+,返回值:+ret);

}

@AfterThrowing(value = mypointcut(),throwing = ex)

private void exceptionHandler(JoinPoint jp,Exceptionex){

logger.debug(AspectJAspectAno--【异常通知】:增强的方法名:+jp.getSignature().getName());

logger.debug(AspectJAspectAno--【异常信息】:+ex.getMessage());

}

@Around(mypointcut())

private Object around(ProceedingJoinPoint pjp)throws Throwable{

Object ret = pjp.proceed();//调用下一个方法

logger.debug(AspectJAspectAno--【环绕通知】:+pjp.getSignature().getName());

return ret;

}

}

3.引入aop,context命名空间

?xml version=1.0 encoding=UTF-8?

beans xmlns=

xmlns:xsi=

xmlns:aop=

xmlns:context=

xsi:schemaLocation=

4.设定bean的扫描路径

!--设定扫描包的路径 --

context:component-scan base-package=org.fjh/

5.设定aspectJ自动代理

!--使用aspectJ自动代理

proxy-target-class:采用JDK动态代理还是cglib

true:cglib方式

false:jdk动态代理(默认)

一般不设定,因新版本aspectJ会自动识别--

aop:aspectj-autoproxy proxy-target-class=false /

6.取得bean

@Test

public void aspectJTest()

{

IUserServiceBean bean =(IUserServiceBean) ctx.getBean(userServiceBean);

bean.addUser(rose);

}

注意:

采用注解的通知执行顺序

前置-环绕-最终-后置(没有异常)

前置-环绕-异常-后置(发生异常)

解决方案:

将其它4种增强(通知)的代码都放在环绕通知中

@Around(mypointcut())

private Objectaround(ProceedingJoinPoint pjp)throws Throwable{

Object ret = null;

try {

//前置增强码

ret = pjp.proceed();//调用下一个方法

//后置增强代码

} catch (Exception o)

{

//异常增强代码

} finally {

//最终增强代码

}

}

以上就是(Spring框架 spring-aop (spring框架的优点))全部内容,收藏起来下次访问不迷路!