spring aop浅析

         spring最核心的也就属ioc和aop了,虽然知道ioc和aop的原理,但在项目中只用到了ioc,aop没用到,所以这里对aop进行一下总结。

spring aop英文全名Aspect Orient Programming 也就是面向方面编程,它是对面向对象编程的一种补充,被专门用来处理系统中分布于各个模块中的交叉关注点的问题,例如在javaee应用中aop常被用来处理一些具有横切性质的系统级服务如事务管理,安全检查,缓存,对象池管理等。AOP框架通过自动生成代理来实现业务的扩充,spring AOP有两种生成代理的方式,一种是JDK的动态代理,一中时CGLIB的,这两种的区别在于如果目标对象实现了接口,spring AOP就会使用jdk的动态代理,如果目标对象没有实现接口,它就会使用CGLIB的。关于jdk的动态代理在设计模式系列的文章中已经详述,这里就不多说,下面我们来使用spring aop来完成功能的扩充。

首先导入spring的jar包,这里直接截图:

因为我是先把spring和struts2整合了一下才测试的,所以里面包含了一些struts2的jar包,这里只看spring 的

实现aop必须的包:

1、aopalliance.jar

AOP Alliance(http://aopalliance.sourceforge.net/) 是个联合的开源协作组织,在多个项目间进行协作以期提供一套标准的AOP Java接口(interface)。 Spring AOP就是基于AOP Alliance标准API实现的。如果你打算使用Spring的AOP或基于AOP的任何特性,只需这个JAR文件。

2、aspectjrt.jar和aspectjweaver.jar,如果你的目标对象没有实现目标接口,你还得导入cglib的jar包,这里只是测试实现接口的目标对象,所以不导入了,其他一些必要的spring包比如核心包等大家应该都知道。

接下来我们在配置文件spring.xml文件中进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
classpath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context 
classpath:/org/springframework/context/config/spring-context-3.0.xsd
http://www.springframework.org/schema/aop 
classpath:/org/springframework/aop/config/spring-aop-3.0.xsd
">
	<!-- 指定自动搜索 Bean 组件、自动搜索方面类 -->
	<context:component-scan base-package="com.dxy.service.impl,com.dxy.test"> 
	 	<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> 
	</context:component-scan>
	<!-- 启动@Aspect支持 -->
	<aop:aspectj-autoproxy/>
	
</beans>


对于spring.xml文件中的以这样的方式引入xsd文件,是因为网速慢,所以解析xsd文件出错,不得不用本地的xsd文件,具体原因见:

http://blog.csdn.net/legendj/article/details/9950963

接着创建接口UserServiceI.java:

package com.dxy.service;

public interface UserServiceI {
	
	public String add();
}

创建实现:

package com.dxy.service.impl;

import org.springframework.stereotype.Service;

import com.dxy.service.UserServiceI;
@Service("userService")
public class UserServiceImpl implements UserServiceI {

	@Override
	public void add() {
		System.out.println("hello world");
	}
	
}

接着定义一个方面,并使用spring AOP的Around增强处理:

package com.dxy.test;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
//定义一个方面
@Aspect
public class AroundAdviceTest {
	@Around("execution(* com.dxy.service.impl.*.*(..))")
	public void log(ProceedingJoinPoint jp) {
		System.out.println("test add start");
		try {
			jp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		System.out.println("test add end");
	}
}

ok,我们在客户端可以调用了:

package com.dxy.test;

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

import com.dxy.service.UserServiceI;

public class MainTest {
	
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring.xml");
		UserServiceI userService = (UserServiceI)ac.getBean("userService",UserServiceI.class);
		System.out.println(userService.getClass());
		userService.add();
	}
}

运行结果:

这样就成功的在add方法前后加上了日志处理,我们通过打印userService的类型得到的是一个代理类class $Proxy8如果使用cglib的话就会生成一个cglib的代理。通过以上示例我们可以知道AOP 代理其实是由 AOP 框架动态生成的一个对象,该对象可作为目标对象使用。AOP 代理包含了目标对象的全部方法,但 AOP 代理中的方法与目标对象的方法存在差异:AOP 方法在特定切入点添加了增强处理,并回调了目标对象的方法。

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值