http://aspectwerkz.codehaus.org/weaving.html
я есть Java-приложение, построенное на Spring 3. У этого проекта есть еще один jar в качестве зависимости.
Эта зависимость содержит@org.aspectj.lang.annotation.Aspect
класс (скажем,com.aspectprovider.aspects.MyAspect
). Это@Before
совет по созданию метода из классов, реализующих интерфейсFoo
, Что-то вроде:
@Before("execution(* com.project.Foo.save(..))")
Foo
Интерфейс может быть внутри «проекта» или в другой банке. Это не имеет значения для этого примера.
Мой проект содержит классы, которые реализуютFoo
, Конечно, я хочу, чтобы это были классы.
Файл конфигурации контекста приложения My Spring (applicationContext.xml
) содержит строку:
<aop:aspectj-autoproxy />
Я также объявляю аспект как bean-компонент и добавляю некоторые свойства:
<bean id="myAspect" class="com.aspectprovider.aspects.MyAspect"
factory-method="aspectOf" >
<property name="someproperty" value="somevalue" />
</bean>
Через логи я вижу чтоMyAspect
создается и свойства вводятся. Но метод сохранения не перехватывается. Это проблема.
Если я скопирую классы аспектов из jar в приложение с Spring, это сработает. Когда эти аспекты содержатся во внешних банках, метод save не перехватывается. Есть какие-нибудь подсказки?
редактировать: как я вызываю метод сохранения Фу:
//in a JSF managed bean
@Inject
private Foo myFoo; //there's a implementation of Foo in a package that spring is looking at. So it is injected correctly.
public String someAction() {
myFoo.save("something"); //the @Before advice is only called if the class containing the aspect is not in an external jar
}
//in a class with a main method
void main(String[] ars) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//right after the previous line, I can see in the log that MyAspect is instantiated.
Foo myFoo = ac.getBean(Foo.class);
myFoo.save("something"); //the @Before advice is only called if the class containing the aspect is not in an external jar
}
В основном мойapplicationContext.xml
имеет следующие строки:
<context:annotation-config />
<context:component-scan base-package="com.project" />
<context:component-scan base-package="com.aspectprovider.aspects" />
<aop:aspectj-autoproxy />
<bean id="myAspect" class="com.aspectprovider.aspects.MyAspect" factory-method="aspectOf" >
<property name="someproperty" value="somevalue" />
</bean>
Я не думаю, что нужно ставить что-то вроде
<context:component-scan base-package="com.project">
<context:include-filter type="aspectj" expression="com.aspectprovider.aspects.*" />
</context:component-scan>