一、
- 引入cglib.jar包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.8</version>
</dependency>
2、 dispatcherServlet-servlet.xml添加配置
<!-- 通知spring使用cglib而不是jdk的來生成代理方法 AOP可以攔截到Controller -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<context:component-scan base-package="com.qding">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
3、applicationContext.xml
<context:component-scan base-package="com.qding">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
二、問題描述
1、當使用Spring AOP對Controller層的Controller類的方法進行切面攔截,不起作用。AOP配置沒有任何問題。
AOP之所以有的人說攔截不到Controller,原因是該註解的Controller已被spring容器內部代理了。我們只要把它交給cglib代理就可以了。Spring MVC的配置文件dispatcherServlet-servlet.xml:
dispatcherServlet-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 登錄攔截器
<mvc:interceptors>
<bean >
</bean>
</mvc:interceptors>-->
<context:annotation-config />
<context:component-scan base-package="com.yc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean class="com.yc.controller.aop.LogAspect" />
<!--SpringMVC的配置文件,包含網站跳轉邏輯的控制,配置 -->
<context:component-scan base-package="com.yc.controller" use-default-filters="false">
<!--只掃描控制器。 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- Spring的配置文件,這裏主要配置和業務邏輯有關的 -->
<!--=================== 數據源,事務控制,xxx ================ -->
<context:property-placeholder location="classpath:properties/*.properties" />
<!-- 靜態資源解析 -->
<mvc:resources location="/webframes/" mapping="/webframes/**"/>
<!--配置視圖解析器,方便頁面返回 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--兩個標準配置 -->
<!-- 將springmvc不能處理的請求交給tomcat -->
<mvc:default-servlet-handler/>
<!-- 能支持springmvc更高級的一些功能,JSR303校驗,快捷的ajax...映射動態請求 -->
<mvc:annotation-driven/>
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="com.yc">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- Spring的配置文件,這裏主要配置和業務邏輯有關的 -->
<context:property-placeholder location="classpath:properties/*.properties" />
<!--sql server 數據源配置 -->
<!-- org.springframework.jdbc.datasource.DriverManagerDataSource -->
<bean id="pooledDataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="filters" value="${filters}" />
<property name="maxActive" value="${maxActive}" />
<property name="initialSize" value="${initialSize}" />
<property name="maxWait" value="${maxWait}" />
<property name="minIdle" value="${minIdle}" />
<property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
<property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${validationQuery}" />
<property name="testWhileIdle" value="${testWhileIdle}" />
<property name="testOnBorrow" value="${testOnBorrow}" />
<property name="testOnReturn" value="${testOnReturn}" />
<property name="poolPreparedStatements" value="${poolPreparedStatements}" />
<property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}" />
</bean>
<!--================== 配置和MyBatis的整合=============== -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis全局配置文件的位置 -->
<property name="configLocation" value="classpath:spring/mybatis-config.xml"></property>
<property name="dataSource" ref="pooledDataSource"></property>
<!-- 指定mybatis,mapper文件的位置 -->
<!-- <property name="mapperLocations" value="classpath:mapper/*.xml"></property> -->
</bean>
<!-- 配置掃描器,將mybatis接口的實現加入到ioc容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--掃描所有dao接口的實現,加入到ioc容器中 -->
<property name="basePackage" value="com.yc.mapper"></property>
</bean>
<!-- 配置一個可以執行批量的sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="SIMPLE"></constructor-arg>
</bean>
<!--============================================= -->
<!-- ===============事務控制的配置 ================ -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制住數據源 -->
<property name="dataSource" ref="pooledDataSource"></property>
</bean>
<!--開啓基於註解的事務,使用xml配置形式的事務(必要主要的都是使用配置式) -->
<aop:config>
<!-- 切入點表達式 -->
<aop:pointcut expression="execution(* com.yc.service..*(..))"
id="txPoint" />
<!-- 配置事務增強 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint" />
</aop:config>
<!--配置事務增強,事務如何切入 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="check*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- Spring配置文件的核心點(數據源、與mybatis的整合,事務控制) -->
<!-- 國際化配置 -->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>properties/messages</value>
</list>
</property>
<property name="defaultEncoding" value="utf-8" />
</bean>
</beans>
3/Spring Aop 執行兩次原因(1)
切面bean重複定義
類中使用了@Component的同時又在springmvc.xml中配置了<bean id="log**" class="com.demo.log.**Aspect"></bean>
方法: 刪除兩個定義之一