Код для демонстрации внедрения Spring AOP привел к длинному ответу. Надеюсь, это поможет
Рассмотрим следующий интерфейс
package rg.test.aop;
public interface UserService {
void sayHello();
}
и две реализации
UserServiceOneImpl
package rg.test.aop.one;
import org.springframework.stereotype.Service;
import rg.test.aop.UserService;
@Service
public class UserServiceOneImpl implements UserService {
@Override
public void sayHello() {
System.out.println("One");
}
}
и UserServiceTwoImpl
package rg.test.aop.two;
import org.springframework.stereotype.Service;
import rg.test.aop.UserService;
@Service
public class UserServiceTwoImpl implements UserService {
@Override
public void sayHello() {
System.out.println("Two");
}
}
, а также интерфейс и его реализация, которые будут представлены в AOP
package rg.test.aop.intro;
public interface LoginTracker {
String FIELD = "Field";
Integer incrementLoginCount();
}
Реализация
package rg.test.aop.intro;
public class DefaultLoginTracker implements LoginTracker {
Integer count = 5;
@Override
public Integer incrementLoginCount() {
return ++count;
}
}
Spring AOP рекомендует применять одинаково для всех классов в пакете rg.test.aop.two
package rg.test.aop.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;
import rg.test.aop.intro.DefaultLoginTracker;
import rg.test.aop.intro.LoginTracker;
@Aspect
@Component
public class IntroTestAspect {
@DeclareParents(value="rg.test.aop.two.*+", defaultImpl=DefaultLoginTracker.class)
LoginTracker tracker;
}
Реализуемый интерфейс определяется типом аннотированного поля. (Здесь LoginTracker
)
Любой компонент соответствующего типа реализует интерфейс LoginTracker
.
Теперь, когда вы запускаете следующий тестовый класс
//package and imports
public class IntroductionTest {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(IntroductionConfig.class);
LoginTracker tracker = ctx.getBean(LoginTracker.class);
System.out.println(tracker);
System.out.println("------------------------");
UserService userOne = (UserService) ctx.getBean("userServiceOneImpl");
UserService userTwo = (UserService) ctx.getBean("userServiceTwoImpl");
printDetails(userOne);
System.out.println("------------------------");
printDetails(userTwo);
ctx.registerShutdownHook();
}
private static void printDetails(Object obj) throws Exception {
System.out.println("Is LoginTracker type :"+LoginTracker.class.isAssignableFrom(obj.getClass()));
System.out.println("Is UserService type :"+UserService.class.isAssignableFrom(obj.getClass()));
System.out.println("Implemented Interfaces : ");
for (Class clazz : obj.getClass().getInterfaces()) {
System.out.println(clazz);
}
System.out.println("Methods : ");
for (Method method : obj.getClass().getMethods()) {
System.out.println(method);
}
System.out.println("Fields : ");
for (Field field : obj.getClass().getFields()) {
System.out.println(field);
}
// If Advised
if (Advised.class.isAssignableFrom(obj.getClass())) {
LoginTracker us = (LoginTracker) obj;
System.out.println(us.incrementLoginCount());
}
}
}
Печатает следующий журнал (Примечание: только соответствующие части журнала скопированы здесь для удобства.)
rg.test.aop.two.UserServiceTwoImpl@c15d8b
------------------------
Is LoginTracker type :false
Is UserService type :true
Implemented Interfaces :
interface rg.test.aop.UserService
Methods :
public void rg.test.aop.one.UserServiceOneImpl.sayHello()
Fields :
------------------------
Is LoginTracker type :true
Is UserService type :true
Implemented Interfaces :
interface rg.test.aop.UserService
interface rg.test.aop.intro.LoginTracker
interface org.springframework.aop.SpringProxy
interface org.springframework.aop.framework.Advised
interface org.springframework.core.DecoratingProxy
Methods :
public final java.lang.Integer com.sun.proxy.$Proxy19.incrementLoginCount()
public final void com.sun.proxy.$Proxy19.sayHello()
Fields :
public static final java.lang.String rg.test.aop.intro.LoginTracker.FIELD
Count :6
Журнал показывает методы и поля, которые были введены для bean-компонента UserServiceTwoImpl.