如何解决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