天天看點

Spring的AOP配置以及常見錯誤(内附代碼)

首先我們可以建立一個包,目錄結構如下:

User類:

package com.hqj.aop;

public class User {

    @Override

    public String toString() {

        return "User [username=" + username + ", password=" + password + "]";

    }

    private String username;

    private String password;

    public String getUsername() {

        return username;

    public void setUsername(String username) {

        this.username = username;

    public String getPassword() {

        return password;

    public void setPassword(String password) {

        this.password = password;

}

Spring的AOP配置以及常見錯誤(内附代碼)

User類接口:

public interface UserDao {

    public void save(User user);

Spring的AOP配置以及常見錯誤(内附代碼)

User類接口類實作:

public class UserDaoImpl implements UserDao {

    public void save(User user) {

        System.out.println("User is saved successfully");

Spring的AOP配置以及常見錯誤(内附代碼)

LogInterceptor類:

public class LogInterceptor {

    public void before() {

        System.out.println("method state");

    public void after() {

        System.out.println("method after");

    public void AfterReturning() {

        System.out.println("method AfterReturning");

    public void AfterThrowing() {

        System.out.println("method AfterThrowing");

Spring的AOP配置以及常見錯誤(内附代碼)

AOP 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:p="http://www.springframework.org/schema/p"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:aop="http://www.springframework.org/schema/aop"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd

    http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop-4.1.xsd

    ">

    <bean id="user" class="com.hqj.aop.User">

        <property name="username" value="Tim"></property>

        <property name="password" value="123"></property>

    </bean>

    <!-- 配置Bean -->

    <bean id="UserDaoImpl" class="com.hqj.aop.UserDaoImpl"></bean>

    <!-- 配置切面的Bean -->

    <!-- 也就是要記錄的資料的地方 (比如錯誤日志) -->

    <bean id="logInterceptor" class="com.hqj.aop.LogInterceptor"></bean>

    <!-- 配置AOP -->

    <aop:config proxy-target-class="true">

        <!-- 配置切點表達式 -->

        <aop:pointcut expression="execution(* com.hqj.aop.UserDao.save(..))"

            id="servicePointcut" />

        <!-- 配置切面以及通知(指向切面,比如錯誤日志) -->

        <aop:aspect id="logAspect" ref="logInterceptor">

            <!-- method寫切面中(比如錯誤日志)的方法名稱 -->

            <aop:before method="before" pointcut-ref="servicePointcut" />

            <aop:after method="after" pointcut-ref="servicePointcut" />

        </aop:aspect>

    </aop:config>

</beans>

Spring的AOP配置以及常見錯誤(内附代碼)

測試MAIN函數:

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {

        // TODO Auto-generated method stub

        ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");

        UserDaoImpl UDI = (UserDaoImpl) ctx.getBean("UserDaoImpl");

        User user = (User) ctx.getBean("user");

        UDI.save(user);

Spring的AOP配置以及常見錯誤(内附代碼)

運作結果:

Spring的AOP配置以及常見錯誤(内附代碼)

常見錯誤:

com.sun.proxy.$Proxy2 cannot be cast to com.hqj.aop.UserDaoImpl

    at com.hqj.aop.Main.main(Main.java:12)

Spring的AOP配置以及常見錯誤(内附代碼)

解決辦法:

<tx:annotation-driven transaction-manager="transactionManager"

                                       proxy-target-class="true"/>

  注意:proxy-target-class屬性值決定是基于接口的還是基于類的代理被建立。如果proxy-target-class 屬性值被設定為true,那麼基于類的代理将起作用(這時需要cglib庫)。如果proxy-target-class屬值被設定為false或者這個屬性被省略,那麼标準的JDK 基于接口的代理将起作用。

        即使你未聲明 proxy-target-class="true" ,但運作類沒有繼承接口,spring也會自動使用CGLIB代理。高版本spring自動根據運作類選擇 JDK 或 CGLIB 代理package com.hqj.aop;