Spring AOP pas de travail pour l'appel de méthode à l'intérieur d'une autre méthode
Il y a deux méthodes définies dans ABC.java
public void method1(){
.........
method2();
...........
}
public void method2(){
...............
...............
}
Je veux avoir de l'AOP sur call of method2.Donc,
J'ai créé une classe,AOPLogger.java,ayant l'aspect de la fonctionnalité fournie dans une méthode checkAccess
Dans le fichier de configuration, j'ai fait quelque chose comme ci-dessous
<bean id="advice" class="p.AOPLogger" />
<aop:config>
<aop:pointcut id="abc" expression="execution(*p.ABC.method2(..))" />
<aop:aspect id="service" ref="advice">
<aop:before pointcut-ref="abc" method="checkAccess" />
</aop:aspect>
</aop:config>
Mais quand mon method2 est appelé, AOP fonctionnalité n'est pas chargé, c'est à dire checkAccess méthode n'est pas chargé de AOPLogger classe.
Quelque chose que je suis absent?
Vous devez vous connecter pour publier un commentaire.
L'aspect est appliqué à un proxy entourant le haricot. Notez que chaque fois que vous obtenez une référence à un haricot, ce n'est pas vraiment la classe référencée dans votre config, mais de façon synthétique les classe implémentant les interfaces pertinentes, en déléguant à la classe réelle et l'ajout de fonctionnalités, telles que votre AOP.
Dans votre exemple ci-dessus, vous appelez directement sur la classe, alors que si l'instance de classe est injecté dans l'autre, comme un Ressort de haricot, il est injecté comme son fondé de pouvoir, et donc les appels de méthode sera invoquée sur le proxy (et les aspects sera déclenchée)
Si vous voulez obtenir le ci-dessus, vous pouvez diviser
method1
/method2
dans distinct, des haricots, ou de l'utilisation d'un non-printemps-orienté AOP cadre.La Printemps doc (section "fonctionnement de l'AOP Procurations") les détails, et un couple de solutions (y compris ma première suggestion ci-dessus)
Il peut être fait par auto-injection d'utilisation. Vous pouvez appeler méthode interne par injecté exemple:
Depuis le Printemps 4.3 vous pouvez également le faire à l'aide de @Autocâblés.
J'ai eu le même genre de problème et j'ai surmonté par la mise en œuvre du Printemps
ApplicationContextAware
,BeanNameAware
et la mise en œuvre de méthodes correspondantes ci-dessous.puis j'ai remplacé
this.
avec((ABC) applicationContext.getBean(beanName)).
tout en appelant les méthodes de la même classe. Cela garantit que les appels aux méthodes de la même classe se produire à travers le proxy.Donc
method1()
changements àEspère que cette aide.
Spring AOP cadre de "proxy" en fonction et c'est très bien expliqué ici:
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies
Quand le Printemps construit un haricot qui est configuré avec un aspect (comme "ABC" dans votre exemple), il crée en fait un "proxy" de l'objet qui agit comme la vraie fève. Le proxy délègue simplement les appels à la "vraie" objet mais par la création de cette indirection, le mandataire obtient une chance de mettre en œuvre les "conseils". Par exemple, vos conseils pouvez enregistrer un message pour chaque appel de méthode. Dans ce schéma, si la méthode dans l'objet réel ("method1") appelle d'autres méthodes dans le même objet (par exemple, method2), ces appels se produire sans proxy dans l'image, donc il n'y a aucune chance pour elle de mettre en œuvre tous les conseils.
Dans votre exemple, quand method1() est appelée, le proxy va avoir une chance de faire ce que jamais il est censé faire, mais si method1() appelle method2(), il n'y a pas d'aspect de l'image. Comment jamais, si method2 est appelé à partir d'un autre bean, proxy sera en mesure de mener à bien les conseils.
Espère que cette aide.
Grâce,
Raghu
À l'aide de
@Autowired
il fonctionne.Au lieu d'appeler la méthode intérieure comme
this.method()
, vous pouvez le faire:puis en appelant:
Il n'est pas possible ce que vous voulez atteindre. Une explication se trouve dans le Printemps De La Documentation De Référence.
Comme indiqué dans le Printemps docs, chapitre 5.6.1 la Compréhension de l'AOP procurations, il est une autre façon que vous pouvez faire:
Bien que l'auteur n'a pas recommander cette façon. Parce que:
Vous pouvez faire l'auto-injection de cette façon, de sorte que cette classe peut être utilisée à l'extérieur de Printemps de l'application.
Annoter des appels avec @EnableAspectJAutoProxy(exposeProxy = true) et d'appeler les méthodes d'instance avec ((Classe) AopContext.currentProxy()).méthode();
Ce n'est strictement pas recommandée, car elle augmente à l'accouplement
Je suis étonné que personne n'a mentionné cela, mais je crois que nous pouvons utiliser ControlFlowPointcut fourni par Spring.
ControlFlowPointcut regarde stacktrace et les matches de la coupe transverse (pointcut) seulement s'il trouve une méthode particulière dans la stacktrace. essentiellement coupe transverse (pointcut) n'a d'égale que lorsqu'une méthode est appelée dans un contexte particulier.
Dans ce cas, nous pouvons créer une coupe transverse (pointcut) comme
maintenant, à l'aide de ProxyFactory créer un proxy sur MyClass instance et d'appel method1().
Dans le cas ci-dessus, seulement method2() sera conseillé car il est appelé à partir de method1().