aop:面向切面编程,个人的理解就是,在不改变目标程序源码码的情况下,动态的在程序执行之前或者之后执行一些业务方法。
加入现在有一个登录注册的业务接口:
package com.project.service;
public interface IUserService {
public void login();
public void register();
}
接口实现类:
package com.project.service.impl;
import com.project.service.IUserService;
public class UserServiceImpl implements IUserService {
@Override
public void login() {
System.out.println("执行登录业务中");
}
@Override
public void register() {
System.out.println("执行注册业务中");
}
}
使用通知,添加一些功能,如记录用户登录时间、日志记录等。
前置通知,实现 MethodBeforeAdvice
接口
package com.project.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class Advice01 implements MethodBeforeAdvice{
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("记录登录时间。。。");
}
}
后置通知,需实现 AfterReturningAdvice
接口
package com.project.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class Advice02 implements AfterReturningAdvice {
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("记录日志");
}
}
环绕通知,实现MethodInterceptor
导 apache 的包
package com.project.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class Advice03 implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// 执行目标业务之前执行
System.out.println("执行业务方法之前执行");
// 调用目标程序的方法
Object result = arg0.proceed();
// 执行目标业务之前执行
System.out.println("执行业务方法之后执行");
return result;
}
}
配置 spring 的配置文件,springConfig.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册实现类 -->
<bean id="UserServiceImpl" class="com.project.service.impl.UserServiceImpl"></bean>
<!-- 注册通知类 -->
<bean id="Advice01" class="com.project.advice.Advice01"></bean>
<bean id="Advice02" class="com.project.advice.Advice02"></bean>
<bean id="Advice03" class="com.project.advice.Advice03"></bean>
<!-- 注册动态代理工厂对象 -->
<bean id="proxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 注入目标对象 -->
<property name="target" ref="UserServiceImpl"></property>
<!-- 注入通知对象 -->
<property name="interceptorNames" value="Advice01, Advice02, Advice03"></property>
</bean>
</beans>
测试函数:
package com.project.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.project.service.IUserService;
public class TestMain {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("springConfig.xml");
IUserService service = (IUserService) context.getBean("proxyFactory");
service.login();
}
测试结果:
结果
有五种通知,这里只简单介绍了常用的三种通知的使用方法。
网友评论