問題:當使用Spring AOP對Controller層的Controller類的方法進行切面攔截,不起作用。AOP配置沒有任何問題。
分析:斷點調試:Spring源碼斷點調試,在調用Controller方法時,Controller的實例被JDK進行動態代理了;
解決:Spring默認的代理方式為JDK動態代理,而Controller層是沒有接口實現的,所以Jdk無法對Controller接口進行動態代理,接口就無法攔截。不用接口的代理方式我們自然想到cglib,于是增加了cglib的代理配置<aop:aspectj-autoproxy proxy-target-class="true" />
Spring MVC和 Spring 整合的時候,SpringMVC的dispatcher-servlet.xml文件中配置掃描包,不要包含 service的注解,Spring的applicationContext.xml文件中配置掃描包時,不要包含controller的注解,如下所示:
Spring MVC dispatcher-servlet.xml:
<context:component-scan?base-package="com.service"><context:exclude-filter type="annotation"?expression="org.springframework.stereotype.service" /></context:component-scan>
Spring MVC啟動時的配置文件,包含組件掃描、url映射以及設置freemarker參數,讓spring不掃描帶有@Service注解的類。為什么要這樣設置?因為springmvc.xml與applicationContext.xml不是同時加載,如果不進行這樣的設置,那么,spring就會將所有帶@Service注解的類都掃描到容器中,等到加載applicationContext.xml的時候,會因為容器已經存在Service類,使得cglib將不對Service進行代理,直接導致的結果就是在applicationContext 中的事務配置不起作用,發生異常時,無法對數據進行回滾。以上就是原因所在。
同樣的在Spring的applicationContext.xml配置如下:
?<context:component-scan?base-package="com.web"><context:exclude-filter type="annotation"?expression="org.springframework.stereotype.Controller" /></context:component-scan>
掃描指定的包中的類上的注解,常用的注解有:
@Controller聲明Action組件
@Service聲明Service組件 ???@Service("myMovieLister")
@Repository聲明Dao組件
@Component泛指組件,當不好歸類時.
@RequestMapping("/menu")請求映射
@Resource用于注入,( j2ee提供的 ) 默認按名稱裝配,@Resource(name="beanName")
@Autowired用于注入,(srping提供的) 默認按類型裝配
@Transactional( rollbackFor={Exception.class})事務管理
@ResponseBody
@Scope("prototype")設定bean的作用域