AOP的介紹AOP(Aspect-OrientedProgramming,面向方面編程)AOP的幾個概念1.切麵(Aspect):切麵就是一個關註點的模塊化,如事務管理、日誌管理、許可權管理等;2.連接點(Joinpoint):程式執行時的某個特定的點,在Spring中就是一個方法的執行;3.通知(A...
AOP的介紹
AOP(Aspect-OrientedProgramming,面向方面編程)
AOP的幾個概念
1.切麵(Aspect):切麵就是一個關註點的模塊化,如事務管理、日誌管理、許可權管理等;
2.連接點(Joinpoint):程式執行時的某個特定的點,在Spring中就是一個方法的執行;
3.通知(Advice):通知就是在切麵的某個連接點上執行的操作,也就是事務管理、日誌管理等;
4.切入點(Pointcut):切入點就是描述某一類選定的連接點,也就是指定某一類要織入通知的方法;
5.目標對象(Target):就是被AOP動態代理的目標對象;
這裡使用登錄功能做日誌管理案例
概要
1)LoginService LogService TestMain
2)用Spring 管理 LoginService 和 LogService 的對象
3)確定哪些連接點是切入點,在配置文件中
4)將LogService封裝為通知
5)將通知植入到切入
6)客戶端調用目標點
Step1 新建登錄業務介面以及實現類
package com.aaron.log; /** * @Author Aaron * @Date創建時間:2016-1-13 * @Version 1.0 * * @Project_Package_Description SpringQuartzDemo || com.aaron.log * @Function_Description登錄業務邏輯 * */ public interface ILoginService { public boolean login(String name, String password); }
package com.aaron.log; /** * @Author Aaron * @Date創建時間:2016-1-13 * @Version 1.0 * * @Project_Package_Description SpringQuartzDemo || com.aaron.log * @Function_Description登錄業務邏輯介面實現類 * */ public class LoginServiceImpl implements ILoginService { public boolean login(String userName, String password) { System.out.println("用戶登錄信息:" + userName + "," + password); return true; } }
Step2 新建日誌管理介面以及實現類
package com.aaron.log; import org.aspectj.lang.JoinPoint; /** * @Author Aaron * @Date創建時間:2016-1-13 * @Version 1.0 * * @Project_Package_Description SpringQuartzDemo || com.aaron.log * @Function_Description日誌介面 * */ public interface ILogService { //無參的日誌方法 public void beforeLog(); //有參的日誌方法 public void Log(JoinPoint point); //有參有返回值的方法 public void afterLog(JoinPoint point,Object returnObj); }
package com.aaron.log; import org.aspectj.lang.JoinPoint; /** * @Author Aaron * @Date創建時間:2016-1-13 * @Version 1.0 * * @Project_Package_Description SpringQuartzDemo || com.aaron.log * @Function_Description記錄日誌介面實現類 * */ public class LogServiceImpl implements ILogService { // 無參方法 public void beforeLog() { System.out.println("*************開始記錄日誌*******************"); } // 有參無返回值的方法 public void Log(JoinPoint point) { // 此方法返回的是一個數組,數組中包括request以及ActionCofig等類對象 Object[] args = point.getArgs(); System.out.print("目標參數列表:"); for (Object obj : args) { System.out.print(obj + ","); } System.out.println(); } // 有參並有返回值的方法 public void afterLog(JoinPoint point, Object returnObj) { // 此方法返回的是一個數組,數組中包括request以及ActionCofig等類對象 Object[] args = point.getArgs(); System.out.print("目標參數列表:"); for (Object obj : args) { System.out.print(obj + ","); } System.out.println(); System.out.println("執行結果是:" + returnObj); System.out.println("*************結束記錄日誌*******************"); } }
Step3 在applicationContext.xml文件中配置AOP
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!-- 啟動觸發器的配置開始 --> <bean name="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="myJobTrigger" /> </list> </property> </bean> <!-- 啟動觸發器的配置結束 --> <!-- 調度的配置開始 --> <!-- quartz-1.8以前的配置 <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail"> <ref bean="myJobDetail" /> </property> <property name="cronExpression"> <value>0/1 * * * * ?</value> </property> </bean> --> <!-- quartz-2.x的配置 --> <bean id="myJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> <ref bean="myJobDetail" /> </property> <property name="cronExpression"> <value>0 0/1 * * * ?</value> </property> </bean> <!-- 調度的配置結束 --> <!-- job的配置開始 --> <bean id="myJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="myJob" /> </property> <property name="targetMethod"> <value>work</value> </property> </bean> <!-- job的配置結束 --> <!-- 工作的bean --> <bean id="myJob" class="com.tgb.lk.demo.quartz.MyJob" /> <bean id="logService" class="com.aaron.log.LogServiceImpl"></bean> <bean id="loginService" class="com.aaron.log.LoginServiceImpl"></bean> <aop:config> <!-- 切入點 --> <aop:pointcut expression="execution(* com.aaron.log.LoginServiceImpl.*(..))" id="myPointcut" /> <!-- 切麵:將哪個對象中的哪個方法,織入到哪個切入點 --> <aop:aspect id="dd" ref="logService"> <!-- 前置通知 --> <aop:before method="beforeLog" pointcut-ref="myPointcut" /> <aop:after method="Log" pointcut-ref="myPointcut"/> <aop:after-returning method="afterLog" returning="returnObj" pointcut-ref="myPointcut" /> </aop:aspect> </aop:config> </beans>applicationContext.xml
Step4 測試方法
package com.aaron.log; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author Aaron * @Date 創建時間:2016-1-13 * @Version 1.0 * * @Project_Package_Description SpringQuartzDemo || com.aaron.log * @Function_Description 測試 * */ public class TestMain { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath*:config/spring/applicationContext.xml"); ILoginService loginService = (ILoginService) ctx.getBean("loginService"); loginService.login("aaron", "123456"); } }
Step5 運行,看後臺
PS:使用註解可以參考別人寫的這篇博客 http://blog.csdn.net/oathevil/article/details/7288867