AOP的引例:
在以往我们在做Servlet项目的时候,当我们设计好了项目,但是有想往代码中添加新的功能,我们能做的就是,修改源代码。但是有没有什么好的方法来解决修改源码的问题呢?
我们设计一个登录程序:
现在我想增加一个新的权限判断功能
AOP相关的概念
1、AOP的概述
AOP为Aspect Oriented Programmaing 的缩写,意味:面向切面编程
AOP是一种编程范式,隶属于软工范畴,指导开发者如何指针程序结构
AOP最早由AOP联盟组织提出们制定了一套规范,Spring将AOP思想引入到框架中,必须遵循AOP规范。
通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
利用AOP,对业务进行隔离,使得业务逻辑各部分之间的耦合度降低。提高程序的可重用性,同时提高开发效率
2、AOP的优势
AOP底层实现原理:(核心就是增强)
JDK动态代理技术(接口实现增强)
1、为接口创建代理类的字节码文件
2、使用ClassLoader将字节码文件加载到jvm
3、创建代理类的实例对象,执行对象的目标方法
cglib代理技术(继承实现增强)
为类生成代理对象,被代理类有没有接口都无所谓,底层是生成子类,继承被代理类
Spring的AOP技术-配置文件方式
1、AOP的相关术语
Joinpoint(连接点)类里面有哪些方法可以增强这些方法称为连接点
Pointcut(切入点)所谓的切入点是指我们要对哪些Joinpoint进行拦截定义
Advice(通知/增强)所谓的通知是指,拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知,后置通知,环绕通知,最终通知,异常通知
Aspect(切面) 是切入点+通知的结合。
2、准备工作
AspectJ是一个面向切面的框架,它扩展了JAVA语言。AspectJ定义了AOP语法,AspectJ实际上是对AOP编程思想的一个实践。
AOP配置文件方式:
创建maven,并添加坐标依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--AOP联盟-->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!--Spring Aspects-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--aspectj-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
创建被增强的类
// 被增强的类
public class User {
//连接点/切入点
public void add(){
System.out.println("add......");
}
public void update(){
System.out.println("update......");
}
}
配置xml文件,将目标类配置到Spring中
<bean id="user" class="com.aopImpl.User"></bean>
定义切面类
public class UserProxy {
//增强/通知 ---》前置通知
public void before(){
System.out.println("before.............");
}
}
在配置文件中定义切面类
<bean id="userProxy" class="com.aopImpl.UserProxy"></bean>
在配置文件中完成AOP的配置
前置通知:
<!--配置切面-->
<aop:config>
<!--配置切面=切入点+通知-->
<aop:aspect ref="userProxy">
<!--前置通知-->
<aop:before method="before" pointcut="execution(public void com.aopImpl.User.add())"></aop:before>
</aop:aspect>
</aop:config>
测试:
public class DemoTest {
@Test
public void aopTest1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) applicationContext.getBean("user");
user.add();
}
}