您的位置:首页 > 编程语言 > Java开发

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

2017-05-12 12:06 561 查看

前言

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

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



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

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

搭建环境

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

新建一个
Java Project
,命名为
JSpring AOP
,我的工作空间字符编码默认是
UTF-8
,所以你们Clone下来后乱码的话就把项目字符编码改成
UTF-8


JSpring-IoC的代码Clone或则Download下来。考虑到别人的IDE环境跟我的未必相同,所以在提交项目的时候我是忽略eclipse配置文件如
.project
.classpath
等文件的,这样子你就不能通过eclipse直接引入该工程了。所以你需要在你的IDE(可以是别的)新建一个工程,工程名随意,然后将
JSpring-IoC
的代码拷贝到相应的位置。

lib
包下的
jar
Build Path


删除
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


可以看出执行顺序是

执行前置通知
MyBeforeAdvice
中的
before
方法

执行目标对象中的
add
方法

最后输出的是代理类。

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

搭建好的JSpring AOP项目已经上传到Github上

https://github.com/HuangFromJYU/JSpring-AOP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring aop
相关文章推荐