简单描述
AOP (面向切面编程) AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
使用Spring实现AOP
注意:以下的aop,context都需要引入命名空间
导入aspectjweaver包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
第一种方式(Spring API接口)
编写接口
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
实现类
public class UserServiceIml implements UserService{
public void add() {
System.out.println("add");
}
public void delete() {
System.out.println("delete");
}
public void update() {
System.out.println("update");
}
public void select() {
System.out.println("select");
}
}
前后增强
前增强
public class BeforeLog implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"执行了"+method.getName()+"方法");
}
}
后增强
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"执行了"+
method.getName()+"方法"+
"返回的结果集为:"+returnValue);
}
}
Spring中注册导入约束
<!--注册Bean-->
<bean id="userService" class="com.feng.demo01.UserServiceIml"/>
<bean id="beforeLog" class="com.feng.demo01.log.BeforeLog"/>
<bean id="afterLog" class="com.feng.demo01.log.AfterLog"/>
<!--aop配置-->
<aop:config>
<!-- 切入点-->
<aop:pointcut id="pointcut" expression="execution(* com.feng.demo01.UserServiceIml.*(..))"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
第二种方式(自定义类实现)
接口
实现类
接口实现类同上
自定义类
public class DiyPoint {
public void before(){
System.out.println("-----------------执行方法前------------------");
}
public void after(){
System.out.println("-----------------执行方法后------------------");
}
}
注册、配置aop
<!--注册Bean-->
<bean id="userService" class="com.feng.demo01.UserServiceIml"/>
<bean id="diyPoint" class="com.feng.demo02.DiyPoint"/>
<!--第二种:切面,自定义类来实现AOP-->
<aop:config>
<!--标记为一个切面-->
<aop:aspect ref="diyPoint">
<aop:pointcut id="point" expression="execution(* com.feng.demo01.UserServiceIml.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
第三种方式(使用注解实现AOP)
接口
实现类
接口实现类同上
编写注解实现增强类
@Aspect //标记为一个切面
@Component
public class AnnotationPoint {
//自定义切入点
@Pointcut("execution(* com.feng.demo01.UserServiceIml.*(..))")
public void log(){}
@Before("log()")
public void before(){
System.out.println("--------执行方法前-----------");
}
@After("log()")
public void after(){
System.out.println("--------执行方法后----------");
}
@Around("log()")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("-------环绕前");
System.out.println("签名:"+jp.getSignature().getName());
jp.proceed();
System.out.println("-------环绕后");
}
}
注册,开启注解支持
<context:annotation-config/>
<context:component-scan base-package="com.feng.demo03"/>
<aop:aspectj-autoproxy/>
<!--注册Bean-->
<bean id="userService" class="com.feng.demo01.UserServiceIml"/>
测试
采用以上任意一种方式
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}
}