向spring bean中注入自身的代理对象

本文介绍了一种在 Spring 框架中实现自我注入的方法,以解决通过 this 访问实例方法时 @Transactional 注解失效的问题。通过创建一个 BeanPostProcessor 实现类,能够自动为带有特定注解的方法注入自身的 AOP 代理对象。

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

如何解决spring bean通过this访问实例方法时@Transactional失效里提供了一个方案,其实就是专门写一个新的类作一个新的bean用来,然后访问这个专门的代理对象来使spring aop生效。不过要是能直接把某个bean的代理对象注入到被代理对象的话,就可以少写一个新的类了。利用BeanPostProcessor可以实现这个功能。 先写一个annotation用来表示那些方法要注入自身 [java] @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface Self { } [/java] 再写一个bean实现BeanPostProcessor. [java] public class InjectSelfPostProcessor implements BeanPostProcessor { private static final Log LOG = new Log(InjectSelfPostProcessor.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Set<Method> selfMethods = this.findAllSelfAnnotatedMethods(bean); if (!selfMethods.isEmpty()) { injectSelf(selfMethods, bean); } return bean; } Set<Method> findAllSelfAnnotatedMethods(Object bean) throws BeansException { Class clazz = bean.getClass(); Set<Method> methods = findAllSelfAnnotatedMethods(clazz); return methods; } Set<Method> findAllSelfAnnotatedMethods(Class clazz) throws BeansException { Set<Method> selfMethods = new HashSet<Method>(); Method[] methods = clazz.getMethods(); for (Method method : methods) { if (!isAnnotatedSelf(method)) { continue; } if (method.getParameterTypes().length != 1) { continue; } if (!method.getName().startsWith("set")) { continue; } selfMethods.add(method); } if (clazz.getSuperclass() != null) { selfMethods.addAll(this.findAllSelfAnnotatedMethods(clazz.getSuperclass())); } return selfMethods; } boolean isAnnotatedSelf(Method method) { Annotation[] annotations = method.getDeclaredAnnotations(); if (annotations == null) { return false; } for (Annotation annotation : annotations) { if (annotation.annotationType().equals(Self.class)) { return true; } } return false; } void injectSelf(Set<Method> selfMethods, Object bean) { for (Method method : selfMethods) { try { method.invoke(bean, bean); LOG.info("Injected self, class:" + bean.getClass().getName() + ", method: " + method.getName()); } catch (IllegalAccessException e) { throw new FatalBeanException("Fail to inject self", e); } catch (InvocationTargetException e) { throw new FatalBeanException("Fail to inject self", e); } } } } [/java] 然后在applicationContext.xml中配置好这个bean. [xml] <bean id="injectSelfBeanPostProcessor" class="com.my.spring.self.InjectSelfPostProcessor"/> [/xml] 最后,要使用的地方这样写就行了 [java] @Component public class TestBean { private TestBean self; @Self public void setSelf(TestBean testBean) { this.self = testBean; } public void test() { //通过 self调用方法,self是这个对象的代理对象 self.test1(); self.test2(); } @Transactional public void test1() { // do something } @Transactional public void test2() { // do something } } [/java]

转载于:https://my.oschina.net/komodo/blog/919185

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值