六、AOP實現(xiàn)自動的系統(tǒng)日志功能

一、本課目標

  • 掌握SpringAOP的配置

二、使用SpringAOP實現(xiàn)日志輸出

在下面的這個示例中,通過SpringAOP在業(yè)務方法執(zhí)行前后成功添加了日志功能。


image.png

該案例的實現(xiàn)步驟:
1、在線項目中添加SpringAOP的jar文件
2、編寫前置增強和后置增強實現(xiàn)日志功能
3、編寫Spring配置文件,對業(yè)務方法進行增強處理
4、編寫代碼獲取帶有增強處理的業(yè)務對象

2.1示例介紹

1、前置增強和后置增強的文件:


image.png

2、定義切入點:


image.png

3、織入增強處理
織入:在切入點插入增強處理
image.png

2.2示例代碼

實體類代碼:

package entity;

/**
 * 用戶實體類
 */
public class User implements java.io.Serializable {
    private Integer id; // 用戶ID
    private String username; // 用戶名
    private String password; // 密碼
    private String email; // 電子郵件

    // getter & setter
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    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;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

dao層接口:

package dao;

import entity.User;

/**
 * 增加DAO接口,定義了所需的持久化方法
 */
public interface UserDao {
    public void save(User user);
}

dao層實現(xiàn)類

package dao.impl;

import dao.UserDao;
import entity.User;

/**
 * 用戶DAO類,實現(xiàn)IDao接口,負責User類的持久化操作
 */
public class UserDaoImpl implements UserDao {

    public void save(User user) {
        // 這里并未實現(xiàn)完整的數(shù)據(jù)庫操作,僅為說明問題
        System.out.println("保存用戶信息到數(shù)據(jù)庫");
    }
}

service層接口:

package service;

import entity.User;

/**
 * 用戶業(yè)務接口,定義了所需的業(yè)務方法
 */
public interface UserService {
    public void addNewUser(User user);
}

service層實現(xiàn)類(這個地方采用控制反轉(zhuǎn)的方式注入UserDao對象):

package service.impl;

import service.UserService;
import dao.UserDao;
import entity.User;

/**
 * 用戶業(yè)務類,實現(xiàn)對User功能的業(yè)務管理
 */
public class UserServiceImpl implements UserService {

    // 聲明接口類型的引用,和具體實現(xiàn)類解耦合
    private UserDao dao;

    // dao 屬性的setter訪問器,會被Spring調(diào)用,實現(xiàn)設值注入
    public void setDao(UserDao dao) {
        this.dao = dao;
    }

    public void addNewUser(User user) {
        // 調(diào)用用戶DAO的方法保存用戶信息
        dao.save(user);
    }
}

日志增強處理類;

package aop;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
/**
 * 增強處理類
 * @author Administrator
 *
 */
public class UserServiceLogger {
    private static Logger log = Logger.getLogger(UserServiceLogger.class);
    
    public void before(JoinPoint jp) {
        log.info("調(diào)用" + jp.getTarget() + "的" + 
                jp.getSignature() + "方法,方法參數(shù)" +
                Arrays.toString(jp.getArgs()));
    }

    public void afterReturning(JoinPoint jp, Object result) {
        log.info("調(diào)用" + jp.getTarget() + "的" + 
                jp.getSignature() + "方法,方法返回值" +
                result);
    }
}

編寫配置文件:
配置文件的表頭的找法跟之前的控制反轉(zhuǎn)的表頭的找法相同:在解壓下載下來的spring包中——docs——spring-framework-reference——htmlsingle——用谷歌打開index.html——使用ctrl+f查找“spring-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:aop="http://www.springframework.org/schema/aop"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="userDao" class="dao.impl.UserDaoImpl"></bean>
    <bean id="userService" class="service.impl.UserServiceImpl">
        <property name="dao" ref="userDao"></property>
    </bean>
    
    <!-- 聲明增強處理類的bean元素 -->
    <bean id="theLogger" class="aop.UserServiceLogger"></bean>
    
    <aop:config>
        <!-- 定義切入點 -->
        <aop:pointcut id="pointCut" expression="execution(public void addNewUser(entity.User))"/>
        <!-- 織入增強處理 -->
        <aop:aspect ref="theLogger">
            <!-- 前置增強,引入切入點 -->
            <aop:before method="before" pointcut-ref="pointCut"/>
            <!-- 后置增強,引入切入點 ,注入目標方法的返回值result-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointCut" returning="result"/>
        </aop:aspect>
    </aop:config>

</beans>

單元測試代碼:

package test;

import static org.junit.Assert.*;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import entity.User;

import service.UserService;

public class AopTest {

    @Test
    public void test() {
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        User user = new User();
        user.setId(1);
        user.setUsername("test");
        user.setPassword("123456");
        user.setEmail("test.@163.com");
        userService.addNewUser(user);
    }

}

三、小結(jié)

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容