АОП с Spring 3 с использованием аннотаций
Я пытаюсь заставить Аспект работать с Spring 3 и аннотациями.
@Aspect
public class AttributeAspect {
@Pointcut("@annotation(com.mak.selective.annotation.Attribute)")
public void process(){
System.out.println("Inside Process ....");
}
@Around("process()")
public void processAttribute(){
System.out.println("Inside Actual Aspect ..");
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="false" />
<context:component-scan base-package="com.mak.selective.annotation.*" />
<bean name="attribute" class="com.mak.selective.annotation.AttributeAspect"/>
</beans>
МОЙ Тест для проверки Аспекта:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/springcontext/*.xml")
public class AttributeTest {
@Attribute(tableName = "firstTable", columnName = "New Column")
private void getAttribute() {
System.out.println("Inside Attribute call...");
}
@Test
public void testAttributeAspect() {
getAttribute();
}
}
С помощью этого кода я вижу только "Внутренний вызов атрибута...", но ничего из Аспекта. Пожалуйста, руководство.
Получил эту работу, создав новый объект (компонент) и внедрив его в тестовый класс Junit.
3 ответа
Приятно видеть, что вы работаете с XML, но вы могли бы сделать это и из аннотаций.
Проблема в том, что @Aspect
аннотация не является стереотипом Spring, поэтому сканер не регистрирует аспект как Spring Bean. Просто добавьте либо @Service
или же @Component
выше или ниже @Aspect
и он будет зарегистрирован.
Кроме того, либо прямо назовите бин (например, @Service("myNamedService")
) или заставить его реализовать интерфейс (например, public class AttributeAspect implements IAspect {
), согласно стандартному дизайну Spring.
Вам нужно использовать настоящий AspectJ, если вы хотите перехватывать вызовы методов в той же самой форме компонента, где он вызывается. (То, что вы сделали, должно работать, если метод testAttributeAspect() находится в другом компоненте.)
Как сделать настоящий AspectJ?
Использование компилятора AspectJ и ткача позволяет использовать полный язык AspectJ и обсуждается в разделе 7.8, "Использование AspectJ с приложениями Spring".
Несколько вещей:
Во-первых, когда вы делаете советы, вам нужно написать метод совета следующим образом:
@Around(...)
public void aroundAdviceMethod(ProceedingJoinPoint pjp) throws Throwable {
try {
System.out.println("before...");
pjp.proceed();
}
finally {
System.out.println("After...");
}
}
Но также (и это, по крайней мере, применимо, когда вы используете прокси, не совсем уверенный в вашем случае), метод, которым вы даете советы, должен быть публичным (ваш - нет), пружинным (через @Component или иным образом).) и вызывается из класса external, так что прокси-сервер может вступить в силу (также не так в вашем примере). Итак, вам нужно что-то вроде этого:
@Component
public class SomeClass {
@Attribute
public void someMethodCall() {
System.out.println("In method call");
}
}
public class SomeUnitTest {
@Autowired SomeClass someClass;
@Test
public void testAspect() {
someClass.someMethodCall();
}
}