自己实现一个spring-AOP思路

本文详细介绍了如何通过定义切面注解、代理接口、代理链和代理管理器等组件,实现一个简单的基于注解的面向切面编程(AOP)。通过创建切面代理类并利用代理链进行责任链模式的实现,最终在项目启动时生成代理类,为需要的类提供AOP功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

aop的加载顺序要在IOC加载的前面,即是要实例完代理类之后才在这个实例上注入属性。

 实现一个基于注解的aop:

  1、定义一个切面注解 Aspect

/**
 * 切面注解
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Aspect {

    Class<? extends Annotation>  value();
}

  2、定义一个代理接口Proxy,定义一个实现这个接口的抽象类(切面代理  AspectProxy)

/**
 * 代理接口
 */
public interface Proxy {
    /**
     * 执行链式代理
     * @param proxyChain
     * @return
     * @throws Throwable
     */
    Object doProxy(ProxyChain proxyChain) throws Throwable;
}
/**
 * 切面代理
 */
public abstract class AspectProxy implements Proxy {

    private static final Logger logger = LoggerFactory.getLogger(AspectProxy.class);

    @Override
    public final Object doProxy(ProxyChain proxyChain) throws Throwable {
        Object result = null;

        Class<?> cls = proxyChain.getTargetClass();
        Method method = proxyChain.getTargetMethod();
        Object[] params = proxyChain.getMethodParams();

        begin();
        try {
            if (intercept(cls, method, params)) {
               boolean flag = before(cls, method, params);
                if(!flag){
                   return "...";
                }
                  result = proxyChain.doProxyChain();
                after(cls, method, params, result);
            } else {
                result = proxyChain.doProxyChain();
            }
        } catch (Exception e) {
            logger.error("proxy failure", e);
            error(cls, method, params, e);
            throw e;
        } finally {
            end();
        }

        return result;
    }

    public void begin() {
    }

    public boolean intercept(Class<?> cls, Method method, Object[] params) throws Throwable {
        return true;
    }

    public boolean before(Class<?> cls, Method method, Object[] params) throws Throwable {
        return true;
    }

    public boolean after(Class<?> cls, Method method, Object[] params, Object result) throws Throwable {
        return true;
    }

    public void error(Class<?> cls, Method method, Object[] params, Throwable e) {
    }

    public void end() {
    }
}

 3、定义一个代理链ProxyChain

/**
 * 代理链
 *
 */
public class ProxyChain {

    private final Class<?> targetClass;//目标类
    private final Object targetObject;//目标对象
    private final Method targetMethod;//目标方法
    private final MethodProxy methodProxy;//方法代理
    private final Object[] methodParams;//方法参数

    private List<Proxy> proxyList = new ArrayList<Proxy>();//代理列表
    private int proxyIndex = 0;//代理索引

    public ProxyChain(Class<?> targetClass, Object targetObject, Method targetMethod, MethodProxy methodProxy, Object[] methodParams, List<Proxy> proxyList) {
        this.targetClass = targetClass;
        this.targetObject = targetObject;
        this.targetMethod = targetMethod;
        this.methodProxy = methodProxy;
        this.methodParams = methodParams;
        this.proxyList = proxyList;
    }

    public Object[] getMethodParams() {
        return methodParams;
    }

    public Class<?> getTargetClass() {
        return targetClass;
    }

    public Method getTargetMethod() {
        return targetMethod;
    }

    public Object doProxyChain() throws Throwable {
        Object methodResult;
        if (proxyIndex < proxyList.size()) {//如果链还没调用完
            methodResult = proxyList.get(proxyIndex++).doProxy(this);//调用切面代理类,切面代理类会回调
        } else {//调用完成,执行目标对象的业务逻辑
            methodResult = methodProxy.invokeSuper(targetObject, methodParams);
        }
        return methodResult;
    }
}

 4、定义一个代理管理器 ProxyManager,该类会在项目启动的时候就被调用,用来实例化目标类

  

 * 代理管理器
 *
 */
public class ProxyManager {

    @SuppressWarnings("unchecked")
    public static <T> T createProxy(final Class<?> targetClass, final List<Proxy> proxyList) {
        return (T) Enhancer.create(targetClass, new MethodInterceptor() {
            @Override
            public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable {
                return new ProxyChain(targetClass, targetObject, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();//生成完整的代理链职责实例
            }
        });
    }
}

5、AOPHelper,负责项目启动时,获取需要生成代理的类,调用ProxyManager,实例化好这些类后保存实例在beans中,后续访问调用将拥有aop功能。

  

static {
    try {
        Map<Class<?>, Set<Class<?>>> proxyMap = createProxyMap();//获取AspectProxy的子类,如果子类有Aspect注解,获取注解中的值,这个值也是个注解类,根据这个注解类去获取所有含有这个注解类的类(这个是基于注解的aop的关键)
        Map<Class<?>, List<Proxy>> targetMap = createTargetMap(proxyMap);//根据上一步组装将要被代理的目标类的代理链
        for (Map.Entry<Class<?>, List<Proxy>> targetEntry : targetMap.entrySet()) {//变量每个需要被代理的类
            Class<?> targetClass = targetEntry.getKey();
            List<Proxy> proxyList = targetEntry.getValue();
            System.out.println("targetClass:"+targetClass.getName());
            System.out.println("proxyList:"+proxyList.get(0).toString());
            Object proxy = ProxyManager.createProxy(targetClass, proxyList);//实例化
            BeanHelper.setBean(targetClass, proxy);//将实例化好的代理类保存到Beans中

        }
    } catch (Exception e) {
        LOGGER.error("aop failure", e);
    }
}

------------------------------------------------------至此,一个简单的aop开发完成-----------------------------------------

调用:

   

/**
 * 拦截 Controller 所有方法,这里可以做权限控制,日志记录,性能监控等等
 */
@Aspect(Controller.class)
public class ControllerAspect extends AspectProxy {

    private static final Logger LOGGER = LoggerFactory.getLogger(ControllerAspect.class);

    private long begin;

    @Override
    public boolean before(Class<?> cls, Method method, Object[] params) throws Throwable {
        LOGGER.debug("---------- begin ControllerAspect ----------");

        if(true){
            return true;
        }
        return false;
    }

    @Override
    public boolean after(Class<?> cls, Method method, Object[] params, Object result) throws Throwable {

        LOGGER.debug("----------- end ControllerAspect-----------");
        if(true){
            return true;
        }
        return false;
    }
}

 

自己实现一个Spring框架需要以下步骤: 1. 创建IoC容器:首先需要创建一个IoC容器,用于管理和装配各个对象。可以使用一个HashMap来存储对象和对应的名称。 2. 实现依赖注入:依赖注入是Spring框架的核心功能之一。可以使用反射机制,在对象创建时自动注入依赖的对象。通过遍历容器中的对象,查找它们的字段或者方法上的注解,然后通过反射将对应的依赖对象注入进去。 3. 实现bean的生命周期管理:Spring框架可以管理bean的生命周期,可以在bean实例化之前、之后和销毁之前进行一些操作。可以使用接口实现这些功能,例如InitializingBean和DisposableBean。在bean创建完成之后,通过调用对应的方法来执行这些操作。 4. 实现AOP功能:AOP(面向切面编程)是Spring框架的另一个核心功能。可以使用动态代理机制,通过在方法前后插入切面逻辑来实现。可以使用注解或者XML配置来定义切面和切入点。 5. 实现事件发布和监听:Spring框架提供了事件发布和监听的功能。可以通过定义事件类、监听器和监听器注册来实现。在关键的地方发布事件,然后监听器会接收到事件并执行相应的逻辑。 6. 实现事务管理:Spring框架还提供了事务管理的功能。可以使用注解或者XML配置来定义事务的边界和传播行为。可以在方法执行前开启事务,在方法执行后提交或回滚事务。 通过以上步骤,我们可以实现一个简单的Spring框架。这个框架可以完成依赖注入、AOP、事件发布和监听、事务管理等功能。当然,真正的Spring框架还有更多复杂的功能和设计,以上只是一个基本的实现思路
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值