写在前面
本文看下如何实现AOP相关内容。
1:为什么需要AOP
工作中有很多非主业务相关,但又必不可少的内容,比如日志打印,权限校验,事务处理,性能监控等。这些准确来说都是属于一些边缘的例行性代码,这些代码固定写死到程序中显然是不合适的,所以我们就需要AOP来动态的帮我们添加这些内容。
2:正文
正常通过getBean方法获取的就是配置的bean,那么想要实现AOP,其实也很简单,只需要在getBean时返回一个代理对象就可以了,具体该怎么做呢?可以这样子,首先定义一个接口,如果配置的bean该接口类型的,则不直接返回其作为最终bean,而是进一步的调用其内部方法获取最终bean,这个最终bean就是代理bean,定义接口如下:
java
/**
* 提供给用户返回自定义对象作为bean的接口,可以认为是一个为bean定制化预留的接口
* @param <T>
*/
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
其中方法getObject就是用来获取真正的目标bean,这里我们可以返回一个代理对象实现AOP。给出实现类:
java
public class ProxyFactoryBean implements FactoryBean<Object> {
// ...
@Override
public Object getObject() throws Exception {
return getSingletonInstance();
}
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.singletonInstance = getProxy(createAopProxy());
}
System.out.println("----------返回代理类 :" + this.singletonInstance + "--------" + this.singletonInstance.getClass());
return this.singletonInstance;
}
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy();
}
}
为了支持获取不同的代理类,定义接口AopProxy,如下:
java
/**
* 代理类接口,支持返回不同类型的代理类(jdk动态代理,基于asm的代理类等)
*/
public interface AopProxy {
Object getProxy();
}
实现类:
java
package com.hc.minispring.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
Object target;
public JdkDynamicAopProxy(Object target) {
this.target = target;
}
@Override
public Object getProxy() {
Object obj = Proxy.newProxyInstance(JdkDynamicAopProxy.class.getClassLoader(), target.getClass().getInterfaces(), this);
System.out.println("----------创建基于jdk的动态代理类成功: ---------" + obj);
return obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("doAction")) {
System.out.println("-----通过jdk动态代理,代理了类的doAction方法........");
return method.invoke(target, args);
}
return null;
}
}
是基于jdk的动态代理。为了方便获取AopProxy创建工厂类:
java
/**
* 代理类创建对象的工厂类,方便对象创建
*/
public interface AopProxyFactory {
AopProxy createAopProxy(Object target);
}
实现类:
java
package com.hc.minispring.aop;
/**
* 默认代理类工厂,返回基于jdk的动态代理类
*/
public class DefaultAopProxyFactory implements AopProxyFactory {
@Override
public AopProxy createAopProxy(Object target) {
return new JdkDynamicAopProxy(target);
}
}
因为增加了一种获取bean的方式,即基于factorybean的getObject方法,所以我们需要增加新的bean工厂类来支持这种方式,如下:
java
package com.hc.minispring.aop;
import com.hc.minispring.ioc.four_beanfactory_and_event.beans.factory.BeansException;
import com.hc.minispring.ioc.four_beanfactory_and_event.beans.factory.support.DefaultSingletonBeanRegistry;
/**
* 支持获取工厂bean的类,真正获取bean的逻辑由FactoryBean类的实现类提供(用户动态提供,或使用框架已经给出的默认扩展)
*/
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
return factoryBean.getObjectType();
}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName) {
Object object = doGetObjectFromFactoryBean(factory, beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
} catch (BeansException e) {
e.printStackTrace();
}
return object;
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) {
Object object = null;
try {
object = factory.getObject();
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
if (!(beanInstance instanceof FactoryBean)) {
throw new BeansException(
"Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
}
return (FactoryBean<?>) beanInstance;
}
}
接着修改abstractbeanfactory:
java
//public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory, BeanDefinitionRegistry {
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements BeanFactory, BeanDefinitionRegistry {
// ...
public Object getBean(String beanName) throws BeansException {
Object singleton = this.getSingleton(beanName);
// ...
// 支持FacotryBean
if (singleton instanceof FactoryBean) {
System.out.println("发现工厂bean ,尝试从工厂bean获取用户自定义bean-------------- " + beanName + "----------------"+singleton);
return this.getObjectForBeanInstance(singleton, beanName);
} else {
System.out.println("普通的bean,直接从ioc容器中拿到的就是:-------------- " + beanName + "----------------"+singleton);
}
return singleton;
}
}
3:测试
定义测试接口:
java
public interface IAction {
void doAction();
}
实现类:
java
public class Action1 implements IAction {
@Override
public void doAction() {
System.out.println("really do action");
}
}
controller:
java
package com.hc.minispring.web.v7_aop.controller;
public class HelloController {
@Autowired
private IAction action;
@RequestMapping("/hello1746")
public String doTest(/*HttpServletRequest request, HttpServletResponse response*/) {
System.out.println("action: " + action.getClass());
action.doAction();
return "index";
}
}
applicationContext.xml:
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="realaction" class="com.hc.minispring.web.v7_aop.Action1" />
<bean id="action" class="com.hc.minispring.aop.ProxyFactoryBean" >
<property type="java.lang.Object" name="target" ref="realaction"/>
</bean>
<bean id="webBindingInitializer" class="com.hc.minispring.web.v5_databind.DateInitializer"></bean>
<!-- ... -->
</beans>
运行:

源码 。