AOP 底层实现原理
1、核心业务接口与实现

public interface IManager { void add(String item); }

public class IManagerImpl implements IManager { private List<String> list = new ArrayList<>(); @Override public void add(String item) { list.add(item); } }
2、通知接口与实现

public interface Advice { void beforeAdvice(); void afterAdvice(); }

public class AdviceImpl implements Advice { @Override public void beforeAdvice() { System.out.println("Method start time: " + System.currentTimeMillis()); } @Override public void afterAdvice() { System.out.println("Method end time: " + System.currentTimeMillis()); } }
3、动态代理类(关联核心业务与通知切面)

public class ProxyFactory implements InvocationHandler { // 被代理对象 private Object target; // 通知 private Advice advice; /** * 通过目标对象返回动态代理对象 * @return */ public Object getProxy() { Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.beforeAdvice(); Object obj = method.invoke(target, args); advice.afterAdvice(); return obj; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Advice getAdvice() { return advice; } public void setAdvice(Advice advice) { this.advice = advice; } }
4、通过配置文件反射实现代理、业务、通知

public class BeanFactory { Properties prop = new Properties(); public BeanFactory(InputStream input) { try { prop.load(input); } catch (IOException e) { e.printStackTrace(); } } /** * 获取Proxy(代理对象) 的实例 * @param name * @return */ public Object getBean(String name) { // 获取ProxyFactory 的class 名称 String className = prop.getProperty(name + ".proxy"); Object proxy = null; try { // 获取ProxyFactory 的class对象 Class proxyClass = Class.forName(className); proxy = proxyClass.newInstance(); // 根据配置文件实例化target 与 advice对象 Object target = Class.forName(prop.getProperty(name + ".target")).newInstance(); Object advice = Class.forName(prop.getProperty(name + ".advice")).newInstance(); // 通过内省实现对ProxyFactory的属性赋值 BeanInfo beanInfo = Introspector.getBeanInfo(proxyClass); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : propertyDescriptors) { String propertyName = pd.getName(); Method writeMethod = pd.getWriteMethod(); if ("target".equals(propertyName)) { writeMethod.invoke(proxy, target); } else if ("advice".equals(propertyName)) { writeMethod.invoke(proxy, advice); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IntrospectionException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return proxy; } }
5、测试

public class AopTest { public static void main (String[] args) { // 读取配置文件 InputStream input = Thread.currentThread().getContextClassLoader() .getResourceAsStream("cn/latiny/aopa/bean.properties"); // 创建Bean的工厂类 BeanFactory beanFactory = new BeanFactory(input); // 获取代理对象 ProxyFactory proxyFactory = (ProxyFactory)beanFactory.getBean("bean"); // 通过代理对象调用 IManager bean = (IManager)proxyFactory.getProxy(); bean.add("Latiny"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?