1. 程式人生 > >Spring AOP使用Aspectj基於xml方式,初始化Bean引數

Spring AOP使用Aspectj基於xml方式,初始化Bean引數

場景:

大多數實體繼承了一個BaseBean,這裡所做的就是使用Spring的Aop功能實現,攔截到的方法,對其引數做一些處理。

spring-xxx.xml的核心配置:

    <aop:aspectj-autoproxy proxy-target-class="true" />

    <aop:config>
       <!--配置com.xxx.xxx.*.controller包下所有類或介面的所有方法-->
       <aop:pointcut id="businessService" expression="execution(* com.xxx.xxx.*.controller.*.*(..))"
/>
<aop:aspect id="TestAspect" ref="aspectBean"> <aop:before pointcut-ref="businessService" method="doBefore"/> <aop:after pointcut-ref="businessService" method="doAfter"/> <aop:after-throwing pointcut-ref="businessService" method="doThrowing"
throwing="ex"/>
</aop:aspect> </aop:config> <bean id="aspectBean" class="com.xxx.xxx.common.TestAspect" />

切點類:

package com.xxx.xxx.common;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import
org.aspectj.lang.JoinPoint; import org.slf4j.LoggerFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.xxx.xxx.bean.BaseBean; import com.xxx.xxx.bean.LoginUser; public class TestAspect { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TestAspect.class); public void doAfter(JoinPoint jp) { LOGGER.debug("log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public void doBefore(JoinPoint jp) throws Exception { Object[] args = jp.getArgs(); for (Object object : args) { // 判斷獲取的引數物件是不是繼承了BaseBean if (BaseBean.class.isAssignableFrom(object.getClass())) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession httpSession = request.getSession(); if (httpSession == null) { LOGGER.error("獲取session失敗"); } LoginUser loginUser = (LoginUser) httpSession.getAttribute(Constants.LOGIN_USER); Class father = httpSession.getAttribute(Constants.LOGIN_USER).getClass().getSuperclass(); try { // 獲取父類setLoginBean方法 Method method = father.getMethod("setLoginBean", new Class[] { LoginUser.class }); // 使用反射機制可以打破封裝性,導致了java物件的屬性不安全 // method.setAccessible(true); // 反射呼叫父類方法 method.invoke(object, new Object[] { loginUser }); } catch (Exception e) { LOGGER.error(e.getStackTrace() + ":" + e.getMessage()); } } } LOGGER.debug("log Begining method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + "[PARAMS]:" + jp.getArgs().toString()); } public void doThrowing(JoinPoint jp, Throwable ex) { LOGGER.error("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); LOGGER.error(ex.getStackTrace() + ":" + ex.getMessage()); } }

注:這裡攔截的類是Controller,並非Service,而在攔截ControllerService的時候spring對切點的配置是有一些不一樣的,關於Spring在位元組碼增強的方面,筆者剛接觸Spring不久,現在恐怕還沒能力解釋什麼,這裡不多說,免得誤導了大家。有很多前輩已經給我們指明瞭前路,感興趣的可以自行百度。

學生淺薄,望眾師指點

wengang.liu