2014-05-15 6 views
5

ich versuche, eine pointcut zu machen, die SQL-Abfragen

@Before("execution(* org.springframework.jdbc.core.JdbcTemplate.*(String, ..))") 
public void logSQLQueries() { 
     System.out.println("@@"); 
    } 

Ich versuche einzuloggen, wie hier den Code zu implementieren; http://www.gotoquiz.com/web-coding/programming/java-programming/log-sql-statements-with-parameter-values-filled-in-spring-jdbc/

aber ich bekomme

java.lang.IllegalArgumentException: Can not set org.springframework.jdbc.core.JdbcTemplate field com.xyz.abc.dao.ABCDaoImpl.jdbcTemplate to com.sun.proxy.$Proxy53 

ich die jdbcTemplate Bohne in meinem * -servlet.xml erstellt haben und autowired dies in allen meinen DAOs. Funktioniert einwandfrei, aber das Hinzufügen des Pointcuts gibt die Ausnahme. Irgendwelche Ideen ??

+0

Programm statt konkreten Klassen Schnittstellen. Spring verwendet Proxys, um AOP anzuwenden. Anstelle von 'JdbcTemplate' verwenden Sie' JdbcOperations', letzteres ist die Schnittstelle (die Sie wahrscheinlich auch in Ihrem Ointcut verwenden möchten).Oder wechseln Sie von schnittstellenbasierten Proxys zu klassenbasierten Proxys oder verwenden Sie keine Proxies, sondern verwenden Sie das Loadtime Weben, um Aspekte anzuwenden. –

+0

Das Beispiel, auf das Sie zeigen, macht sogar, was @M.Deinum Ihnen gerade gesagt hat, Sie haben es geändert! BTW, Spring AOP funktioniert auch mit Klassen anstelle der bevorzugten Schnittstellen, aber dann benötigen Sie CGLIB auf Ihrem Klassenpfad. – kriegaex

+0

Ich habe zuerst mit der Schnittstelle versucht, aber als es nicht funktionierte, versuchte ich etwas anderes. Ich verstehe das Konzept der Proxies hier nicht. Können Sie mir bitte einen Hinweis geben, wo ich das Konzept verstehen kann? Außerdem, wie wechsle ich zu klassenbasiertem Proxy oder benutze Ladezeitweben. Danke für die Antwort, bitte eine Antwort, damit ich sie markieren kann. – SKaul

Antwort

8

Spring verwendet standardmäßig JDK Dynamic Proxies, um AOP anzuwenden. (Weitere Informationen zu Proxies finden Sie unter here).

Es wird eine dynamische Klasse erstellt (com.sun.proxy.$Proxy53), die alle Schnittstellen implementiert, die die Zielklasse implementiert. Für eine JdbcTemplate ist das JdbcOperations und InitializingBean. Die dynamische Klasse ist also eine JdbcOperations, aber keine JdbcTemplate und daher schlägt die Injektion fehl.

Sie haben ein paar Lösungen

  1. die Schnittstelle verwenden JdbcOperations anstelle der Klasse JdbcTemplate zu programmieren gegen
  2. Gebrauchsklasse basiert Proxies
  3. Verwenden Ladezeit Weben

Jetzt Option 1 und 2 sind am einfachsten, während Option 3 am leistungsstärksten und komplexesten ist (siehe die unten stehenden Links).

Für 1 in der Klasse ändern

@Autowired 
private JdbcTemplate jdbcTemplate; 

Um

@Autowired 
private JdbcOperations jdbcTemplate; 

Wenn Sie JdbcDaoSupport erweitern Sie in eine Gurke sein könnte und dann wird es nicht funktionieren.

Option 2, vorausgesetzt, Sie haben <aop:aspectj-autoproxy />, setzen Sie das Attribut proxy-target-class auf true. Dies erfordert cglib und erstellt klassenbasierte Proxies anstelle von interface-basierten Proxies.

Für Option 3 beziehe ich mich auf the reference guide, da dies (wahrscheinlich) ein Java-Agent beinhaltet und möglicherweise ein wenig komplizierter zu arbeiten ist.

Verbindungen

  1. Understanding AOP proxies
  2. Load-time weaving with AspectJ
+0

Danke! Löste mein Problem. – SKaul

+0

Versuchte ersten zwei Lösungen, sie funktionieren nicht. Zumindest im Frühjahr 4.2.x – user1159819

+0

Dann haben Sie ein anderes Problem (im Grunde die erste sollte immer funktionieren, wenn das nicht funktioniert; t haben Sie einige, wie es geschafft, zu ermöglichen, (wahrscheinlich) einen Proxy eines Proxy zu erstellen). –

Verwandte Themen