Мне удалось что-то взломать, основываясь на этом примере Spring AOP .
Я еще не освоил Spring 3, поэтому я реализовал это с помощью Spring 2.5 - осмелюсь сказать, что есть более элегантные способы достижения того, чего вы хотите. Я реализовал это, используя System.out для простоты, но их можно легко преобразовать в вызовы log4j.
Сначала я создаю карту между именами bean-компонентов Spring и строковым представлением объекта ( InitBean ). Эта карта используется внутри MethodInterceptor - я попытался сделать MethodInterceptor InitializingBean , но MethodInterceptor по какой-то причине перестал работать.
Выполнение равных между компонентом, переданным через MethodInterceptor , и другими компонентами в контексте приложения не сработало. например используя что-то вроде " ctx.getBeansOfType (GoBean.class) " внутри MethodInterceptor . Я предполагаю, что это потому, что объект, переданный через MethodInvocation , был GoBean , тогда как объекты, полученные из контекста приложения в этой точке, являются прокси (например, что-то вроде пример .GoBean $$ EnhancerByCGLIB $$ bd27d40e ).
Вот почему мне пришлось прибегнуть к сравнению строковых представлений объекта (что не идеально). Также я специально не хочу активировать логику MethodInterceptor при вызове метода " toString " для объекта (так как использование toString в другом месте приводит к бесконечные циклы и StackOverflow).
Надеюсь, это полезно,
applicationContext.xml
<beans>
<bean name="initBean" class="example.InitBean"/>
<bean name="methodLoggingInterceptor" class="example.MethodLoggingInterceptor">
<property name="initBean" ref="initBean"/>
</bean>
<bean name="proxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>go*</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>methodLoggingInterceptor</value>
</list>
</property>
</bean>
<bean name="goBean1" class="example.GoBean" />
<bean name="goBean2" class="example.GoBean" />
<bean name="goBean3" class="example.GoBean" />
</beans>
GoBean.java
public class GoBean {
public void execute(){
System.out.println(new Date());
}
}
SimpleTestClass.java
public static void main( String[] args ){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ArrayList<GoBean> goBeans = new ArrayList<GoBean>();
goBeans.add((GoBean) ctx.getBean("goBean1"));
goBeans.add((GoBean) ctx.getBean("goBean2"));
goBeans.add((GoBean) ctx.getBean("goBean3"));
for(GoBean g: goBeans){
g.execute();
}
}
InitBean.java
public class InitBean implements ApplicationContextAware, InitializingBean {
private ApplicationContext ctx;
private Map<String, String> beanMap = new HashMap<String,String>();
public void setApplicationContext(ApplicationContext ac) throws BeansException {
ctx = ac;
}
public void afterPropertiesSet() throws Exception {
for(String beanName: ctx.getBeanNamesForType(GoBean.class)){
beanMap.put(ctx.getBean(beanName).toString(), beanName);
}
}
public Map<String,String> getBeanMap(){
return beanMap;
}
}
MethodLoggingInterceptor.java
public class MethodLoggingInterceptor implements MethodInterceptor{
private InitBean initBean;
public Object invoke(MethodInvocation method) throws Throwable {
if (!"toString".equals(method.getMethod().getName())) {
StringBuilder sb = new StringBuilder();
Object obj = method.getThis();
if (obj instanceof GoBean) {
Map<String,String> beanMap = initBean.getBeanMap();
String objToString = obj.toString();
if (beanMap.containsKey(objToString)) {
System.out.println(beanMap.get(objToString));
sb.append("bean: ");
sb.append(beanMap.get(objToString));
sb.append(" : ");
}
}
sb.append(method.getMethod().getDeclaringClass());
sb.append('.');
sb.append(method.getMethod().getName());
System.out.println(sb.toString() + " starts");
Object result = method.proceed();
System.out.println(sb.toString() + " finished");
return result;
} else {
return method.proceed();
}
}
public void setInitBean(InitBean ib) {
this.initBean = ib;
}
}