後端-框架-Spring-AOP 事物增強

後端-框架-Spring-AOP-註解注入

如果碰到代碼無誤,可能是JDK與aspectjweaver版本不匹配

pointcut位置

package cn.service;

import cn.service.UserService;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import cn.dao.UserDao;
import cn.entity.User;

/**
 * 用戶業務類,實現對User功能的業務管理
 */
@Service("UserService")
public class UserServiceImpl implements UserService {
	private UserDao dao;
	
	@Resource(name="UserDao")
	public void setDao(UserDao dao) {
		this.dao = dao;
	}
	
	public UserServiceImpl(UserDao dao) {
		this.dao=dao;
	}

	public void addNewUser(User user) {
		dao.save(user);
	}
}

日誌類

package cn.aop;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class UserServiceLogger {
	public static Logger logger = Logger.getLogger(UserServiceLogger.class);
	
	//此處定義通用的pointcut
	@Pointcut("execution(* cn.service.UserService.*(..))")
	public void pointcut(){}
	
	@Before("pointcut()")
	public void before(JoinPoint jp){
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法參數"+Arrays.toString(jp.getArgs()));
	}
	@AfterReturning(pointcut="execution(* cn.service.UserService.*(..))",returning="result")
	public void afterReturn(JoinPoint jp,Object result){
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法返回值"+result);
	}
	@AfterThrowing(pointcut="execution(* cn.service.UserServiceImpl.*(..))",throwing="e")
	public void afterThrow(JoinPoint jp,Exception e){
		logger.error(jp.getSignature().getName()+"捕捉到異常"+e);
	}
	@After("pointcut()")
	public void after(JoinPoint jp){
		logger.info(jp.getSignature().getName()+"最終增強");
	}
	@Around("pointcut()")
	public Object around(ProceedingJoinPoint jp) throws Throwable{
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法參數"+Arrays.toString(jp.getArgs()));
		try {
			Object result = jp.proceed();
			logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法返回值"+result);
			return result;
		} catch (Throwable e) {
			logger.error(jp.getSignature().getName()+"捕捉到異常"+e);
			throw e;
		} finally{
			logger.info(jp.getSignature().getName()+"方法結束");
		}
	}
}

準備的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:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd"
    >
    <context:component-scan base-package="cn.dao,cn.service"/>
    
	<bean id="UserServiceLogger" class="cn.aop.UserServiceLogger"></bean>
	<!-- 啓動Spring對AOP AspectJ註解支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	
</beans>

後端-框架-Spring-AOP 事物增強-普通注入


Declaring Advice Value
aop:before
aop:after-returning
aop:after-throwing
aop:after
aop:around
記錄日誌類
package cn.aop;

import java.util.Arrays;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;

public class UserServiceLogger {
	public static Logger logger = Logger.getLogger(UserServiceLogger.class);
	public void before(JoinPoint jp){
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法參數"+Arrays.toString(jp.getArgs()));
	}
	public void afterReturn(JoinPoint jp,Object result){
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法返回值"+result);
	}
	public void afterThrow(JoinPoint jp,Exception e){
		logger.error(jp.getSignature().getName()+"捕捉到異常"+e);
	}
	public void after(JoinPoint jp){
		logger.info(jp.getSignature().getName()+"最終增強");
	}
	public Object around(ProceedingJoinPoint jp) throws Throwable{
		logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法參數"+Arrays.toString(jp.getArgs()));
		try {
			Object result = jp.proceed();
			logger.info("調用對象:"+jp.getTarget()+"方法:"+jp.getSignature()+"方法返回值"+result);
			return result;
		} catch (Throwable e) {
			logger.error(jp.getSignature().getName()+"捕捉到異常"+e);
			throw e;
		} finally{
			logger.info(jp.getSignature().getName()+"方法結束");
		}
	}
}
用戶業務類
package cn.service;

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

/**
 * 用戶業務類,實現對User功能的業務管理
 */
public class UserServiceImpl implements UserService {

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

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

	public void addNewUser(User user) {
		// 調用用戶DAO的方法保存用戶信息
		dao.save(user);
		throw new RuntimeException("測試異常");
	}
}
ApplicationContext配置
<?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-4.3.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop.xsd"
    >
    
	<bean id="UserDao" class="cn.dao.UserDaoImpl"></bean>
	<bean id="UserService" class="cn.service.UserServiceImpl">
		<property name="dao" ref="UserDao"/>
	</bean>
	<bean id="UserServiceLogger" class="cn.aop.UserServiceLogger"></bean>
	
	<aop:config>
		<!-- 切入點,切入執行增強的方法 -->
		<aop:pointcut expression="execution(public void addNewUser(cn.entity.User))" id="pointcut"/>
		<!-- 切入面,增強方法定義 -->
		<aop:aspect ref="UserServiceLogger">
			<aop:before method="before" pointcut-ref="pointcut"/>
			<!-- method必須與具體類中方法名一致 -->
			<aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="result"/>
			<aop:after-throwing pointcut-ref="pointcut" throwing="e" method="afterThrow"/>
			<aop:after pointcut-ref="pointcut" method="after"/>
		</aop:aspect>
			<aop:around pointcut-ref="pointcut" method="around"/>
	</aop:config>
	
</beans>

JUnit測試
package test;

import static org.junit.Assert.*;

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

import cn.entity.User;
import cn.service.UserService;
import cn.service.UserServiceImpl;

public class UserServiceTest {

	@Test
	public void test() {
		ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
		UserService us = (UserService) context.getBean("UserService");
		User user = new User();
		user.setId(123);
		user.setPassword("1234444");
		user.setUsername("Caedios");
		user.setEmail("Gmail");
		us.addNewUser(user);
	}
}

別忘了,expression表達式

<aop:pointcut expression="execution(public void addNewUser(cn.entity.User))" id="pointcut"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章