SpringAOP面向切面详解(带实例)

了解AOP的相关术语

1.通知(Advice):

通知定义了切面是什么,以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。

2.连接点(Joinpoint):

程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。

3.切入点(Pointcut):

通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定(切面在哪个方法的前或后做出的那个方法点)

4.切面(Aspect):

通知和切入点共同组成了切面:时间、地点和要发生的“故事”,事务管理是J2EE应用中一个很好的横切关注点例子,切面用Spring的Advisor或拦截器实现

5.引入(Introduction):

引入允许我们向现有的类添加新的方法和属性(Spring提供了一个方法注入的功能)

6.目标(Target):

即被通知的对象,如果没有AOP,那么它的逻辑将要交叉别的事务逻辑,有了AOP之后它可以只关注自己要做的事(AOP让他做爱做的事)

7.代理(proxy):

应用通知的对象,详细内容参见设计模式里面的代理模式

8.织入(Weaving):

把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:

(1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器

(2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码

(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术

存在的实现方式

1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面

实现步骤

1.创建通知:实现这几个接口,把其中的方法实现了
2.定义切点和通知者:在Spring配制文件中配置这些信息
3.使用ProxyFactoryBean来生成代理

范例

例子我是基于maven和Spring注解的方式,用POJO实现

工程的主要文件的配置

pom.xml

4.0.0imoocspringmavenwar0.0.1-SNAPSHOTspringmaven Maven Webapphttp://maven.apache.org    SSHMJ-FRANK        mav        sss        http://mvnrepository.com            true            false        default        org.springframework        spring-aop        3.1.1.RELEASE        org.springframework        spring-asm        3.1.1.RELEASE        org.springframework        spring-aspects        3.1.1.RELEASE        org.springframework        spring-beans        3.1.1.RELEASE        org.springframework        spring-context        3.1.1.RELEASE        org.springframework        spring-context-support        3.1.1.RELEASE        org.springframework        spring-core        3.1.1.RELEASE        org.springframework        spring-expression        3.1.1.RELEASE        org.springframework        spring-instrument        3.1.1.RELEASE        org.springframework        spring-instrument-tomcat        3.1.1.RELEASE        org.aspectj        aspectjweaver        1.6.9        commons-pool        commons-pool        1.5.3        commons-collections        commons-collections        3.2        log4j        log4j        1.2.16        org.springframework        spring-jms        3.1.1.RELEASE        org.springframework        spring-oxm        3.1.1.RELEASE        org.springframework        spring-web        3.1.1.RELEASE        org.springframework        spring-webmvc        3.1.1.RELEASE        org.springframework        spring-webmvc-portlet        3.1.1.RELEASE        org.springframework        spring-struts        3.1.1.RELEASE        commons-httpclient        commons-httpclient        3.1        ognl        ognl        2.6.9        javax.servlet        javax.servlet-api        3.0.1        javax.servlet        jstl        1.2        cglib        cglib        2.2                org.apache.maven.plugins                maven-site-plugin                3.4    springmaven

web.xml

springmaven

org.springframework.web.context.ContextLoaderListenercontextConfigLocationclasspath:applicationContext.xml  spring  org.springframework.web.servlet.DispatcherServlet      contextConfigLocation      classpath:spring-servlet.xml  2  spring  *.html

applicationContext.xml

spring-servlet.xml

IToDo.java

切入点(Pointcut)接口

package com.service.imp;

public interface IToDo {

public String toEat();

}

ToDo.java

package com.service;

import org.springframework.stereotype.Service;

import com.service.imp.IToDo;
@Service
public class ToDo implements IToDo {

@Overridepublic String toEat() {    System.out.println("吃苹果");    return "吃苹果";}

}

IPreDo.java

package com.service.imp;

public interface IPreDo {

public String toPre();

}

application.java

用于测试

package springmaven;

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

import com.service.imp.IToDo;

public class application {
public static void main(String[] args) {
ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");
IToDo tdo = (IToDo)appCtx.getBean("toDo");
tdo.toEat();
}
}

工程图片

超级产品经理

:会自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面,我这里没有使用注解的方式,使用了xml配置的方式。

:就是用来配置aspectJ切面

proxy-target-class:设置代理模式。当poxy-target-class="true"时,表示使用CGLib动态代理技术织入增强。设置为false时,表示使用jdk动态代理织入增强,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。

:设置切面,ref是切面Bean的id名

:这里设置切入点,expression设置切面植入的切入点的方法地址

:在执行切入点方法之前执行切面方法,method为切面中的执行方法,pointcut-ref与切点的id一致就可以了

定义一个AOP通知者
后通知
返回后通知
抛出后通知
周围通知
定义一个切面
前通知
顶级配置元素,类似于这种东西
定义一个切点

讲解

returning:是切点的返回值,在切面中通过returnValue接受,若要获取传给切点的参数在切面的java方法参数中加上JoinPoint,获取的是一个数组,按顺序排列。

package com.service;

import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Service;

import com.service.imp.IPreDo;
@Service
public class PreDo implements IPreDo {

@Overridepublic String toPre(JoinPoint joinPoint,Object returnValue) {    System.out.println("洗手");    System.out.println(joinPoint.getArgs()[0]);    return "洗手";}

}
结果

吃苹果
洗手
121212

参考资料:

Spring实现AOP的4种方式

proxy-target-class

关键字:java, spring, springmvc


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部