自己实现Spring AOP(一)环境搭建及知识准备

#前言
这个项目是基于JSpring IoC的,所以在看下去之前,你要确保看过之前实现JSpring IoC的文章(这些文章在我的博客分类JSpring IoC),不然也不看不出什么意思来,就不用浪费时间往下看了。

在做这个项目的时候发生了一件有趣的事,我发现了JSpring IoC的一个Bug……,在 自己实现Spring IoC容器(四)IoC容器的Bug对这个Bug进行了介绍,也没什么,就是写错了一句代码。有趣的是我的那篇文章被推荐到了首页!!

我真是不知道他们是以什么标准推荐的,我觉得那篇文章真的是没什么出彩的地方。

啥也不说了,继续撸起袖子干吧

#搭建环境

上面我说到这项目是基于JSpring IoC的,所以我先把它给弄好。

  1. 新建一个Java Project,命名为JSpring AOP,我的工作空间字符编码默认是UTF-8,所以你们Clone下来后乱码的话就把项目字符编码改成UTF-8
  2. JSpring-IoC的代码Clone或则Download下来。考虑到别人的IDE环境跟我的未必相同,所以在提交项目的时候我是忽略eclipse配置文件如.project.classpath等文件的,这样子你就不能通过eclipse直接引入该工程了。所以你需要在你的IDE(可以是别的)新建一个工程,工程名随意,然后将JSpring-IoC的代码拷贝到相应的位置。
  3. lib包下的jarBuild Path
  4. 删除JSpring-IoC一些跟测试相关的东西,只保留功能代码。把源码文件test删掉,等下要再重新创建;删除edu.jyu.bean包,这也是测试用到的;删除applicationContext.xml中有关bean的配置,保留根标签beans

上面4步就可以将环境搭建起来了。

现在还需要一些准备知识

#知识准备

我要实现的是JSpring AOP,那么你得有Spring AOP 的相关知识。

在Spring中如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP,如果目标对象没有实现接口,必须采用CGLib(Code Generation Library)方式。

关于这些动态代理的知识可以看Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM),写的很好

至于Spring AOP的一些使用方法,还不了解的还是去找本书来看吧

#要实现的东西
我先用Spring传统的AOP方式(即没有用AspectJ)演示一个例子,搭建Spring环境什么的我就在这介绍了,直接开干

(1)先准备好目标对象相关类和接口

UserDao接口

package edu.jyu.dao;

public interface UserDao {
	public void add(String user);
}

UserDaoImpl类,实现了UserDao接口

package edu.jyu.dao;

public class UserDaoImpl implements UserDao{

	@Override
	public void add(String user) {
		System.out.println("add "+user);
	}
}

(2)编写增强代码,即通知,在此定义一个前置通知,其实还有各种什么后置通知环绕通知等东西,在这里就不去介绍了,自己去了解吧。

package edu.jyu.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class MyBeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		System.out.println("-----------前置通知-----------");
		System.out.println("方法:" + method.getName());
		System.out.println("参数" + args);
		System.out.println("目标对象" + target);
		System.out.println("-----------前置通知-----------");
	}

}


(3)编写配置文件applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p" 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.xsd">
	
	<!-- 目标对象 -->
	<bean id="userDao" class="edu.jyu.dao.UserDaoImpl"></bean>
	
	<!-- 前置通知 -->
	<bean id="beforeAdvice" class="edu.jyu.advice.MyBeforeAdvice"></bean>
	
	<!-- 配置生成代理对象 -->
	<bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 代理的目标对象 -->
		<property name="target" ref="userDao" />
		
		<!-- 代理要实现的接口 -->
		<property name="proxyInterfaces" value="edu.jyu.dao.UserDao" />
		
		<!-- 需要织入目标的通知 -->
		<property name="interceptorNames" value="beforeAdvice" />
	</bean>

</beans>

(4)编写测试类

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

import edu.jyu.dao.UserDao;

public class TestProxy {

	@Test
	public void test() {
		ApplicationContext atx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		//注意这里要获取的是userDaoProxy不是userDao
		UserDao userDao = (UserDao) atx.getBean("userDaoProxy");
		userDao.add("Jason");
		System.out.println(userDao.getClass());
	}
}

运行结果

-----------前置通知-----------
方法:add
参数[Ljava.lang.Object;@64485a47
目标对象edu.jyu.dao.UserDaoImpl@7a30d1e6
-----------前置通知-----------
add Jason
class com.sun.proxy.$Proxy4

可以看出执行顺序是

  1. 执行前置通知MyBeforeAdvice中的before方法
  2. 执行目标对象中的add方法

最后输出的是代理类。

到此一个,Spring AOP的例子就展示完毕,我自己实现的AOP功能就是仿造上面例子的,只不过进行了一些改动。


搭建好的JSpring AOP项目已经上传到Github上
https://github.com/HuangFromJYU/JSpring-AOP

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值