springAOP面向切面编程

了解AOP
我是一个新手,可能表述的不是特别清楚,如果有误,希望可以指点出来。
spring AOP是继spring IOC之后的srping框架的又一大特性,它也是spring框架的核心内容。
AOP是一种思想,所有符合AOP思想的技术,都可以看作AOP的实现,spring框架已经基本吧AOP的思想实现了。在众多的AOP实现技术中,spring AOP做的最好,也很成熟。
spring AOP的实现是基于java的代理机制。
springAOP的基本组成部分。对下面简单实现的概括。
AOP的简单实现:
一个普通的类-》有特定功能的类a.继承类 b.实现接口 c.注解 d.配置

前置通知类的实现

1.模拟三层dao层的实现

package org.awen.dao;

public class studentDao {
	public void addStudent(int id) {
		System.out.println("增加学生");
	}
	public void deleteStudent(int id) {
		System.out.println("删除学生");
	}
}

2.配置applicationContext.xml

<bean id="studentDao" class="org.awen.dao.studentDao">
	
	</bean>
	
	
	<!-- 前置通知类 -->

	
	<bean id="LogBefore" class="org.awen.aop.LogBefore"></bean>
	<aop:config>
		
		
	
		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.addStudent(int))" id="pointcut"/>
		
		<aop:advisor advice-ref="LogBefore" pointcut-ref="pointcut"/>	
	
	
	</aop:config>

3.实现LogBefore,实现一个接口

package org.awen.aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class LogBefore implements MethodBeforeAdvice{

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO 自动生成的方法存根
		System.out.println("前置通知");
	}
	

	
}

4.实现test类,测试类。

package org.awen.test;


import org.awen.dao.studentDao;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	
	public static void testAOP() {
		ApplicationContext contet=new ClassPathXmlApplicationContext("applicationContext.xml");
		//执行从springIOC容器中获取一个id为student的对象
		studentDao studentdao=(studentDao)contet.getBean("studentDao");
		//从ioc中拿方法
		studentdao.addStudent(1);
		studentdao.deleteStudent(1);
		/*
		String[] ids=contet.getBeanDefinitionNames();
		for(String id:ids) {
			System.out.println(id);
		}
		*/
	}
	
	
	public static void main(String[] args) {
		
		testAOP();
		
	}
}

补充说明:

如果同时为两个方法,添加前置通知的话(addStudent和deleteStudent)那么就需要改变applicationContext.xml

		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.deleteStudent(void)) or execution(public void org.awen.dao.studentDao.addStudent(void))" id="pointcut"/>

后置通知类的实现

1.模拟三层dao层的实现
2.配置applicationContext.xml

<bean id="LogAfter" class="org.awen.aop.LogAfter"></bean>
	
	<aop:config>
		
		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.addStudent(int))" id="pointcut2"/>
		
	
		<aop:advisor advice-ref="LogAfter" pointcut-ref="pointcut2"/>	
	
	
	</aop:config>

3.实现LogAfter,实现一个接口

	package org.awen.aop;
	
	import java.lang.reflect.Method;
	
	import org.springframework.aop.MethodBeforeAdvice;
	
	public class LogAfter implements MethodBeforeAdvice{

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO 自动生成的方法存根
		System.out.println("后置通知");
	}

	}

4.实现test类,测试类。

异常通知类的实现

1.模拟三层dao层的实现
2.配置applicationContext.xml

<bean id="afterThrowind" class="org.awen.aop.LogException"></bean>
	
	<aop:config>
		
		
		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.addStudent(int))" id="pointcut3"/>
		
		<aop:advisor advice-ref="afterThrowind" pointcut-ref="pointcut3"/>		
	</aop:config>

3.实现afterThrowind,实现一个接口

	package org.awen.aop;
	
	import java.lang.reflect.Method;
	
	import org.springframework.aop.ThrowsAdvice;
	
	public class LogException implements ThrowsAdvice{
	
	//异常通知得具体方法
	public void afterThrowind(Method method, Object[] args, Object target , Throwable ax){
		System.out.println("异常");
		//System.out.println("异常通知:目标对象"+target+",方法名"+method.getName()+",方法的参数个数:"+args.length+",异常类型:"+ax.getMessage());
	}

	
		}	
		

4.实现test类,测试类。

环绕通知类的实现

1.模拟三层dao层的实现
2.配置applicationContext.xml

<bean id="invoke" class="org.awen.aop.LogAround"></bean>
	
	<aop:config>
		
		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.addStudent(int))" id="pointcut4"/>
		
		
		<aop:advisor advice-ref="invoke" pointcut-ref="pointcut4"/>		
	</aop:config>

3.实现LogBefore,实现一个接口


public class LogAround implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO 自动生成的方法存根
		Object result=null;
		//方法体1...
		try {
			//方法体2..
			System.out.println("用环绕通知实现的【前置通知】");
			result=invocation.proceed();//在此方法之前的都是前置通知,之后的都是后置通知
			System.out.println("用环绕通知实现的【后置通知】");
			System.out.println("异常通知:目标对象"+invocation.getThis()+",方法名"+invocation.getMethod()+",方法的参数个数:"+invocation.getArguments().length);

		}catch(Exception e) {
			//方法体3...

			System.out.println("用环绕通知实现的【异常通知】");

		}
		
		return result;
	}

}

4.实现test类,测试类。

以上都是用实现接口的方法来进行的。



下面都是使用Schema的方法来进行的。

实例,LogSchmema

package org.awen.aopSchemema;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class LogSchmema {
	
	
	public void before() {
		// TODO 自动生成的方法存根
		System.out.println("用schmema实现的前置通知");
	}
	
	
	public void afterReturning(JoinPoint jp,Object objectvalue) {
		System.out.println("用schmema实现的后置通知"+jp.getThis()+objectvalue);
	}
	
	public void whenException(JoinPoint jp) {
		System.out.println("用schmema实现的异常通知");
	}
	
	
	public Object around(ProceedingJoinPoint pj) throws Throwable {
		System.out.println("用schmema实现的环绕前置通知");
		Object result=null;
		try {
			result=pj.proceed();
			System.out.println("用schmema实现的环绕后置通知");
		}catch(Exception e) {
			System.out.println("用schemema实现的环绕异常通知");
		}
		
		return result;
		
	}
}

applicationContext.xml配置:

<!-- 用schmema实现的通知-->
	<bean id="LogSchmema" class="org.awen.aopSchemema.LogSchmema"></bean>
	
	<aop:config>
		<!-- 配置切入点 (在哪里执行通知) -->
		
		<!-- 这是 studentService后面的切入点-->
		<aop:pointcut expression="execution(public void org.awen.dao.studentDao.addStudent(int))" id="schmema"/>
		
		
		<aop:aspect ref="LogSchmema">
			<aop:before method="before" pointcut-ref="schmema"/>
			<aop:after-returning method="afterReturning" returning="objectvalue" pointcut-ref="schmema"/>
			
			
			<aop:after-throwing method="whenException" pointcut-ref="schmema"/>
			
		
			
			<aop:around method="around" pointcut-ref="schmema"/>
			
		</aop:aspect>
		
	</aop:config>

下面是基于注解形式的

1.配置aoolicationContext.xml文件:

<!-- 开启注解对AOP的支持 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	<!-- 通过注解 将其加入IOC中需要一个扫描器 -->
	<context:component-scan base-package="org.awen.aopAnnotation"></context:component-scan>
	

2.编写LogAnnotation.java这个类:

@Component("logAnnotation")//将LogBeforeAnnotation纳入springIOC容器中
@Aspect//此类事一个通知类 这个并不需要扫描器 
public class LogAnnotation{

	
	//前置通知
	@Before("execution(public void org.awen.dao.studentDao.addStudent(int))")
	public void myBefore(JoinPoint jp) {
		System.out.println("异常通知:目标对象"+jp.getTarget()+",方法名"+jp.getSignature().getName()+",方法的参数个数:"+Arrays.toString(jp.getArgs()));

		System.out.println("<注解形式-前置通知>");
	}
	
	//后置通知
	@AfterReturning("execution(public void org.awen.dao.studentDao.addStudent(int))")
	public void myAfter() {
		System.out.println("<注解形式-后置通知>");
	}

	
	
	//环绕通知
	@Around("execution(public void org.awen.dao.studentDao.addStudent(int))")
	public void myAround(ProceedingJoinPoint jp) throws Throwable {
		System.out.println("<注解形式-环绕通知-前置通知>");
		//方法之前:前置通知
		try {
			//方法的执行体
			jp.proceed();
		}catch(Exception e) {
			//发生异常执行的通知
			System.out.println("<注解形式-环绕通知-后置通知>");
		}finally {
			//最终通知
			System.out.println("环绕的最终通知");
		}
		
		
	}
	
	
	
	//异常通知:如果只捕获特定类型的已存在异常
	@AfterThrowing(pointcut="execution(public void org.awen.dao.studentDao.addStudent(int))",throwing="e")
	public void myException(JoinPoint jp,NullPointerException e) {
		System.out.println("<注解形式-异常通知>"+e.getMessage());
	}
	
	//最终通知
	@After("execution(public void org.awen.dao.studentDao.addStudent(int))")
	public void myAfter1() {
		System.out.println("<注解形式-最终i形式----通知>");
	}
	/**/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值