使用pojo+xml开发aop
基于xml的配置是spring专有的.aspectj得到越来越多的支持,具备更好的重用性.
我们可以在xml中配置通知的几种情况,分别为前置通知,后置通知,环绕通知,异常通知和引入通知。
1.首先创建一个类为切面,类中实现的方法为具体的通知,具体的实现为实现的前置通知,后置通知,环绕通知,异常通知和引入通知。类名为AdviceUtil.java,
package cn.csdn.hr.advice;
import org.aspectj.lang.ProceedingJoinPoint;
//切面
public class AdviceUtil {
//前置通知
public void getUp() {
// TODO Auto-generated method stub
System.out.println("老王起来啦!");
}
}
2.然后我们要有业务逻辑,来测试
EmployeeService.java 接口
package cn.csdn.hr.service;
public interface EmployeeService {
// 工作
public void work();
}
实现的具体的类为,EmployeeServiceBean.java:
package cn.csdn.hr.service;
public class EmployeeServiceBean implements EmployeeService {
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("开始工作l===================");
}
}
3.在bean.xml中的配置,首先要引入aop,引入的格式为:
xmlns:aop=http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
所以,在bean.xml中我们可以使用:
<aop:config></aop:config>标签,这个标签aop配置的声明包括了通知和切面
<aop:pointcut></aop:pointcut>标签用来声明切入点
<aop:aspect></aop:aspect>标签用来配置切面
<aop:before/>带有参数的前置通知
<aop:around/>环绕通知
<aop:after/>后置通知
<aop:after-returning />
<aop:after-throwing />
<aop:declare-parents/> 引用通知
对上面声明的类的前置通知的使用代码为:
<?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"
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 -->
<bean id="adviceUtil" class="cn.csdn.hr.advice.AdviceUtil"></bean>
<!-- 声明业务bean -->
<bean id="employeeServiceBean" class="cn.csdn.hr.service.EmployeeServiceBean"></bean>
<!-- aop配置的声明 包括了通知和切面 -->
<aop:config>
<!-- 声明切入点 -->
<aop:pointcut expression="execution(* cn.csdn.hr..*.*work(..))" id="myPointcut"/>
<!-- 配置切面 order是优先级 -->
<aop:aspect ref="adviceUtil">
<!--配置前置通知 method是方法名-->
<aop:before method="getUp" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
然后我们可以一次类推来配置后置通知,在AdviceUtil.java中加入方法为:
//后置通知
public void goHome() {
System.out.println("回家吧!=================");
}
在bean.xml中配置后置通知为:
<!-- 后置通知 -->
<aop:after method="goHome" pointcut-ref="myPointcut"/>
环绕通知为:
//环绕通知
public Object punchCard(ProceedingJoinPoint jp) throws Throwable {
// TODO Auto-generated method stub
System.out.println("打卡前============!");
Object obj = jp.proceed();
System.out.println("打卡后============!");
return obj;
}
在AdviceUtil.java中的配置为:
<!--环绕通知 -->
<aop:around method="punchCard" pointcut-ref="myPointcut"/>
后置通知之后的通知和异常通知为:
//后置通知之后的通知 after-returning
public void back(Object ret){
System.out.println("运行back方法================="+ret);
}
//异常处理通知
public void unwell(Exception ex){
System.out.println("不舒服====================="+ex.getMessage());
}
在bean.xml中的配置为:
<aop:after-returning method="back" pointcut-ref="myPointcut" returning="ret"/>
<aop:after-throwing method="unwell" pointcut-ref="myPointcut" throwing="ex"/>
带有参数的前置通知:
在AdviceUtil.java中添加一个方法:
// 具体的实现为通知
public void checkLogin(String name, String pass) {
System.out.println("检查用户的用户名:" + name + ",密码为:" + pass);
}
在bean.xml中的配置为:
<aop:pointcut expression="execution(* cn.csdn.hr..*.*work(..)) and args(name,pass)" id="myPointcut1"/>
<!-- 带有参数的前置通知-->
<aop:before method="checkLogin" pointcut-ref="myPointcut1"/>
同时还要在service中写一个带有两个参数的方法才可以,在EmployeeService.java中添加的方法为:
public void work(String uname,String upass);
在EmployeeServiceBean.java中实现的方法为:
@Override
public void work(String uname, String upass) {
// TODO Auto-generated method stub
System.out.println(uname+"============="+upass+"==============");
}
这样,才可以实现有参数的前置通知。
引用通知
我们以一个添加最后的时间为例,首先写出Auditable.java的接口来写方法:
package cn.csdn.hr.advice;
import java.util.Date;
public interface Auditable {
//引入 就是添加新的功能 修改日期的接口
//添加属性:记录最后一次修改的时间
void setLastModifiedDate(Date lastModifiefDate);
Date getLastModifiedDate();
}
在AuditableAdvice.java中实现为:
package cn.csdn.hr.advice;
import java.util.Date;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
/*
* 引入通知,继承DelegatingIntroductionInterceptor接口,使用引入的拦截器
*/
@SuppressWarnings("serial")
public class AuditableAdvice extends DelegatingIntroductionInterceptor implements
Auditable {
private Date lastModifiedDate;
//DefaultIntroductionAdvisor
@Override
public void setLastModifiedDate(Date lastModifiefDate) {
// TODO Auto-generated method stub
this.lastModifiedDate = lastModifiefDate;
}
@Override
public Date getLastModifiedDate() {
// TODO Auto-generated method stub
System.out.println("最后一次修改的时间为:"+lastModifiedDate);
return lastModifiedDate;
}
}
在AdviceUtil.java中没有实现的方法,因为在以上的接口和实现类中的已经实现,在bean.xml中的配置为:
<aop:declare-parents types-matching="*..EmployeeServiceBean" implement-interface="cn.csdn.hr.advice.Auditable" default-impl="cn.csdn.hr.advice.AuditableAdvice"/>
测试的方法为:
package cn.csdn.hr.junit;
import java.util.Date;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.csdn.hr.advice.Auditable;
import cn.csdn.hr.service.EmployeeService;
public class AppMain {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
EmployeeService employeeService = (EmployeeService) ac
.getBean("employeeServiceBean");
employeeService.work();
employeeService.work("老王", "222");
Auditable auditable = (Auditable) employeeService;
auditable.setLastModifiedDate(new Date());
System.out.println(auditable.getLastModifiedDate());
}
}
最后测试的结果为:
老王 起来啦!
打卡前============!
开始工作l===================
打卡后============!
回家吧!=================
运行back方法=================null
老王 起来啦!
检查用户的用户名:老王,密码为:222
打卡前============!
老王=============222==============
打卡后============!
回家吧!=================
运行back方法=================null
最后一次修改的时间为:Thu Apr 19 09:15:49 GMT 2012
Thu Apr 19 09:15:49 GMT 2012
使用pojo+xml开发aop
最新推荐文章于 2024-10-18 18:49:38 发布