java - Spring AOP doesn`t work with class comprising @Transactional method -
i develop web-app, need store heavy-weight files , use apache ftp server purpose. when new user register account, folder named username must created on remote server. establish connection, before usercreatingserviceimpl.createuser() method performed, use spring aop:
@component @aspect public class remoteserverconnectionestablisher { private static boolean connectionestablished = false; @autowired private remoteserverconnector serverconnector; @pointcut("execution(* com.storehouse.business.services.impl.usercreatingserviceimpl.createuser(..)) ||" + " execution (* com.storehouse.business.services.impl.itemcreatingserviceimpl.createitem(..)) ||" + "execution (* com.storehouse.business.services.impl.filedownloadingserviceimpl.downloadfile(..))") public void pointcut() { } @before("pointcut()") public void establishconnection(joinpoint jp) { if (!connectionestablished) { if (serverconnector.connecttoremoteserver()) { connectionestablished = true; } } } @after("pointcut()") public void disconnect(joinpoint jp) { if (connectionestablished) { if (serverconnector.disconnect()) { connectionestablished = false; } } } }
here service class createuser() method:
@service public class usercreatingserviceimpl implements usercreatingservice { @autowired private userservice userservice; @autowired private ftpclient ftpclient; @override public boolean createuser(userdto userdto) { try { ftpclient.makedirectory(userdto.getusername()); usermapper usermapper = new usermapper(); userservice.persistuser(usermapper.dtotoentity(userdto)); return true; } catch (ioexception e) { e.printstacktrace(); } return false; } @transactional public void checkifusernameexist(string username) { } }
everything had worked fine, until added @transactional method service -class:
@transactional public void checkifusernameexist(string username) { }
now methods of aspect-class don`t invoke. explain reason. in advance help.
the issue lies in pointcut expression.
execution(* com.storehouse.business.services.impl.usercreatingserviceimpl.createuser(..))
you intercepting the execution of createuser
method on usercreatingserviceimpl
. works when don't add creates proxy implementation. directly calling method.
however have added @transactional
proxy created , method call done on usercreatingservice
interface left due created proxy. default spring uses jdk dynamic proxies, interface based.
to solve 1 of these things
- rewrite pointcut operate on interface instead of implementing class
- use class based instead of interface based proxies
- use compile or load time weaving
rewrite pointcut
use execution(* com.storehouse.business.services.usercreatingservice+.createuser(..))
instead of have now. use interface instead of concrete class.
use class based proxies
assuming use @enableaspectjautoproxy
add proxytargetclass=true
it, leading @enableaspectjautoproxy(proxytargetclass=true)
. create class based proxies , should make original pointcut work.
use compile or load time weaving
instead of using proxies change way code build/loaded. compile time weaving have modify build use aspectj compiler apply aspects @ compilation time, don't need proxies more.
or instead of @enableaspectjautoproxy
add @enableloadtimeweaving
which, if use recent servlet container, weave aspects class being loaded.
both eliminate need proxies (at least part) , make original pointcuts work.
Comments
Post a Comment