著名的spring两大杀手锏:IOC 和 AOP,今天来说下AOP。
缘起:
AOP:面向切面编程,是独立于spring的。spring Aop是AOP的实现框架
之一。
Spring Aop
Spring Aop是用动态代理机制实现的。先简单说下动态代理(大家都知道
代理有两种方式:静态代理和动态代理),动态代理(JDK实现方式)涉
及的四个概念:目标对象、代理对象、InvocatoinHandler接口、Proxy类。
直接上代码:
处理器类:
public class MyInvocationHandler implements InvocationHandler{
//目标对象
private Object target;
private IUserServiceManager userServiceManager;
public MyInvocationHandler(Object target,IUserServiceManager userServiceManager){
this.target = target;
this.userServiceManager = userServiceManager;
}
/**
* 调用
* @param proxy 代理对象
* @param method 目标方法
* @param args 目标方法参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//非核心代码
userServiceManager.before();
//核心业务代码
Object result = method.invoke(target,args);
//非核心代码
userServiceManager.after();
return result;
}
}
增强类接口:
public interface IUserServiceManager {
public void before();
public void after();
}
增强类实现:
public class UserServiceManagerImpl implements IUserServiceManager{
private ThreadLocal<Long> threadLocal = new ThreadLocal<Long>();
@Override
public void before() {
long nowTimeSeconds= System.currentTimeMillis();
threadLocal.set(nowTimeSeconds);
System.out.println("UserServiceManagerImpl before-->time:"+
nowTimeSeconds);
}
@Override
public void after() {
long nowTimeSeconds2= System.currentTimeMillis();
System.out.println("UserServiceManagerImpl after-->time:"+
nowTimeSeconds2);
System.out.println("UserServiceManagerImpl 方法耗时:"+
(threadLocal.get()-nowTimeSeconds2));
}
}
目标类:
public class UserServiceImpl implements IUserService{
@Override
public void add() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("UserServiceImpl add...");
}
}
测试类:
@RunWith(SpringRunner.class)
@ContextConfiguration
public class JDKProxyTest {
@Test
public void jdkProxyTest(){
//生成一个目标对象
IUserService target = new UserServiceImpl();
//增强对象
IUserServiceManager userServiceManager = new UserServiceManagerImpl();
//生成一个handler
MyInvocationHandler handler = new MyInvocationHandler(target,userServiceManager);
//使用JDK生成代理对象
IUserService userService = (IUserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);
//代理对象执行目标方法
userService.add();
}
@Test
public void springAopTest(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(AopProxyConfig.class);
// 第二种方式ctx
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// ctx.register(AopProxyConfig.class);
// ctx.refresh();
IUserService userService = (IUserService) ctx.getBean("userServiceImpl");
userService.add();
}
}
上面将采用Spring Aop后,handler就不用我们自己写了,Spring已经写好了,咱们直接用就行了,
但是需要按照spring提供的规则使用的。只需要定义增强类(切面)就可以了。其他怎么组织是Spring的事情了,但前提是所有的bean都先
归spring进行管理(可以通过打开注解扫描或者使用全注解方式)。代码如下(注意注解):
`
(增强类)切面类:
@Aspect
@Component
public class MyAspect {
@Before("execution(public * mianshi.Proxy.service.*.*(..))")
public void hi(){
System.out.println("切面编程--前置");
}
@After("execution(public * mianshi.Proxy.service.*.*(..))")
public void hi2(){
System.out.println("切面编程--后置");
}
}`
就是这么简单搞定。spring框架还不错。。
测试一下:
@Test
public void springAopTest(){
ApplicationContext ctx = new AnnotationConfigApplicationContext(AopProxyConfig.class);
// 第二种方式ctx
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
// ctx.register(AopProxyConfig.class);
// ctx.refresh();
IUserService userService = (IUserService) ctx.getBean("userServiceImpl");
userService.add();
}
总结:spring ioc利用动态代理的机制实现了面向切面编程。使用场景最多的就是事务和日志处理、监控等。
文章写得有不明白之处,请留言……
转载于:https://blog.51cto.com/jiaxiaoxu/2369646