AOP
AOP意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能统一维护的技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行分离,从而使得业务各个部分之间的耦合度降低,提高程序的可用性,同时提高了开发效率.
AOP在Spring中的作用
提供声明式事务;允许用户自定义切面
- 横切关注点:跨越应用程序多个模块的方法或功能。即使与业务逻辑无关,但是我们需要关注的部分就是横切关注点。如日志,安全,缓存,事务等等…
- 切面(Aspect):横切关注点被模块化的特殊对象。即,他是一个类
- 通知(Advice):切面必须要完成的工作。即,他是类中的一个方法.
- 目标(Target):别通知对象、
- 代理(Proxy):向目标对象应用通知之后创建的对象.
- 切入点(PointCut):切面通知执行的“地点”的定义
- 连接点(JoinPoint):与切入点匹配的执行点.
导maven包
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency>
AOP实例XML
实例接口:
public interface UserService { public void add(); public void delete(); public void update(); public void select(); }
实例实现类:
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("增加了一个用户!!"); } @Override public void delete() { System.out.println("删除一个用户!!"); } @Override public void update() { System.out.println("更新一个用户!!"); } @Override public void select() { System.out.println("查找一个用户!!"); } }
增强业务Log
import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { //method:要执行的方法 //args:参数 //target:目标对象 public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了"); } }
增强业务AfterLog
import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class Log implements MethodBeforeAdvice { //method:要执行的方法 //args:参数 //target:目标对象 public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了"); } }
方式一
XML文件applicationContext.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注册bean--> <bean id="userService" class="com.peng.service.UserServiceImpl"/> <bean id="log" class="com.peng.log.Log"/> <bean id="afterLog" class="com.peng.log.AfterLog"/> <!--配置aop:需要导入aop约束--> <aop:config> <!--切入点:execution表达式execution(要执行的位置!* * * * * )--> <aop:pointcut id="pointcut" expression="execution(* com.peng.service.UserServiceImpl.*(.. ))"/> <!--执行环绕增加!--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
测试类
import com.peng.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //动态代理的是接口 UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService"); userService.add(); } }
结果:
方式二
新增Diy类
public class DiyPointCut { public void before(){ System.out.println("=========方法执行前========"); } public void after(){ System.out.println("=========方法执行后========"); } }
applicationContext.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--注册bean--> <bean id="userService" class="com.peng.service.UserServiceImpl"/> <bean id="log" class="com.peng.log.Log"/> <bean id="afterLog" class="com.peng.log.AfterLog"/> <bean id="diy" class="com.peng.diy.DiyPointCut"/> <aop:config> <!--自定义切面,ref 要引用类--> <aop:aspect ref="diy"> <!--切入点--> <aop:pointcut id="point" expression="execution(* com.peng.service.UserServiceImpl.*(..))"/> <!--通知--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
测试类
public class MyTest { public static void main(String[] args) { ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //动态代理的是接口 UserService userService = (UserService) classPathXmlApplicationContext.getBean("userService"); userService.add(); } }
结果: