1. AOP是什么(Aspect Oriented Programming)
- AOP是一种编程范式,提供从还有一个角度来考虑程序结构以完好面向对象编程(OOP)。
- AOP为开发人员提供了一种描写叙述横切关注点的机制,并可以自己主动将横切关注点织入到面向对象的软件系统中。从而实现了横切关注点的模块化。
- AOP可以将那些与业务无关,却为业务模块所共同调用的逻辑或责任。比如事务处理、日志管理、权限控制等。封装起来,便于降低系统的反复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
2.AOP能干什么,也是AOP带来的优点
- 减少模块的耦合度
- 使系统easy扩展
- 设计决定的迟绑定:使用AOP,设计师能够推迟为将来的需求作决定,由于它
- 能够把这样的需求作为独立的方面非常easy的实现。
- 更好的代码复用性
3.Spring中实现AOP技术:
在Spring中可以通过代理模式来实现AOP
代理模式分为
静态代理:一个接口,分别有一个真实实现和一个代理实现。
动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而 可以在运行期(Runtime)实现动态关联。
动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib
来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有
接口的支持,而cglib不需要,它是基于类的。
4.在 net.biancheng.c.dao 包下,创建一个名为 UserDao 的接口,代码如下。
- package net.biancheng.c.dao;
- public interface UserDao {
- public void add();
- public void delete();
- public void modify();
- public void get();
- }
5.在 net.biancheng.c.dao.impl 包下,创建 UserDao 的实现类 UserDaoImpl,代码如下。
- package net.biancheng.c.dao.impl;
- import net.biancheng.c.dao.UserDao;
- public class UserDaoImpl implements UserDao {
- @Override
- public void add() {
- System.out.println("正在执行 UserDao 的 add() 方法……");
- }
- @Override
- public void delete() {
- System.out.println("正在执行 UserDao 的 delete() 方法……");
- }
- @Override
- public void modify() {
- System.out.println("正在执行 UserDao 的 modify() 方法……");
- }
- @Override
- public void get() {
- System.out.println("正在执行 UserDao 的 get() 方法……");
- }
- }
6.在 net.biancheng.c.advice 包下,创建一个名为 UserDaoBeforeAdvice 的前置增强类,代码如下。
- package net.biancheng.c.advice;
- import org.springframework.aop.MethodBeforeAdvice;
- import java.lang.reflect.Method;
- /**
- * 增强代码
- * MethodBeforeAdvice 前置增强
- *
- */
- public class UserDaoBeforeAdvice implements MethodBeforeAdvice {
- @Override
- public void before(Method method, Object[] args, Object target) throws Throwable {
- System.out.println("正在执行前置增强操作…………");
- }
- }
7.在 src 目录下创建一个 Spring 的配置文件 Beans.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:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
- <!--******Advisor : 代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截(* 不带有切点的切面.针对所有方法进行拦截)*******-->
- <!-- 定义目标(target)对象 -->
- <bean id="userDao" class="net.biancheng.c.dao.impl.UserDaoImpl"></bean>
- <!-- 定义增强 -->
- <bean id="beforeAdvice" class="net.biancheng.c.advice.UserDaoBeforeAdvice"></bean>
- <!--通过配置生成代理 UserDao 的代理对象 -->
- <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
- <!-- 设置目标对象 -->
- <property name="target" ref="userDao"/>
- <!-- 设置实现的接口 ,value 中写接口的全路径 -->
- <property name="proxyInterfaces" value="net.biancheng.c.dao.UserDao"/>
- <!-- 需要使用value:增强 Bean 的名称 -->
- <property name="interceptorNames" value="beforeAdvice"/>
- </bean>
- </beans>
8.在 net.biancheng.c 包下,创建一个名为 MainApp 的类,代码如下。
- package net.biancheng.c;
- import net.biancheng.c.dao.UserDao;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class MainApp {
- public static void main(String[] args) {
- //获取 ApplicationContext 容器
- ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
- //获取代理对象
- UserDao userDao = context.getBean("userDaoProxy", UserDao.class);
- //调用 UserDao 中的各个方法
- userDao.add();
- userDao.delete();
- userDao.get();
- userDao.modify();
- }
- }
9. 执行 MainApp 中的 main 方法,控制台输出如下
正在执行前置增强操作………… 正在执行 UserDao 的 add() 方法…… 正在执行前置增强操作………… 正在执行 UserDao 的 delete() 方法…… 正在执行前置增强操作………… 正在执行 UserDao 的 get() 方法…… 正在执行前置增强操作………… 正在执行 UserDao 的 modify() 方法……