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 运行,看后台