使用pojo+xml开发aop

使用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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值