文档章节

springframe【6】

ruyees
 ruyees
发布于 2014/10/05 11:47
字数 1342
阅读 10
收藏 0
点赞 0
评论 0

AOP之动态代理

 

AOP的原理就是动态代理,上一片介绍了什么是代理,展示了静态代理,很多时候静态代理还是不太灵活的,我们需要动态代理来完成我们的业务逻辑,这里展示下动态代理的创建,并通过代码的注释告诉你,为啥“java的事务是基于代理的”

 1、创建我们的接口,还是上次的IHello接口

 

package com.itcast.aop;
//要实现的接口
public interface IHello {
	public void hello(String name) throws Exception;
	public void helloAaa(String name);
	public void helloBbb(String name);
}

 

2、创建我们的接口实现类。

 

package com.itcast.aop;

//实现方法,用来展示我们的动态代理
public class HelloSpeaker2 implements IHello {
public void hello(String name) {
	System.out.println("Hello2 :hello "+name);
}
public void helloAaa(String name) {
	System.out.println("Hello2 in aaa"+ name);
}
public void helloBbb(String name) {
	System.out.println("Hello2 in bbb"+ name);
}
}

 

3、创建一个实现了动态代理必备参数InvocationHandler接口的实现类。这个是我们整个动态代理的核心点。我们所有的文章都在这个地方下功夫,但是具体如何使用实现这个接口的类,那还要等下一步才能解释了。

 

package com.itcast.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.logging.Logger;
//操作代理类的任何一个方法都会触发这个invoke操作
public class LogHandler implements InvocationHandler {
private Logger logger = Logger.getLogger(this.getClass().getName());
private Object delegate;
public LogHandler(Object obj){
	this.delegate=obj;
}
public Object invoke(Object proxy, Method method, Object[] arg2)
		throws Throwable {
	Object result = null;
	try{
		//看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理
		logger.info("看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理");
		logger.info("开始我们的方法 ..."+method);
		//如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事物?
		logger.info("如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事务?");
		result = method.invoke(delegate, arg2);
		for(Object tmp:arg2){
			System.out.println("InvocationHandler实现类中输出传入的参数值:"+tmp.toString());
		}
		//在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?
		logger.info("在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?");
		logger.info("结束我们的方法..."+method);
	}catch(Exception e){
		e.printStackTrace();
	}
	return result;
}
}

 

闲着没事看一下上边的日志标注,我们的动态代理的核心点就是上边的方法,我输出日志的地方,就是一些额外的附加业务逻辑的最好切入点

 4、将我们的实现类绑定到动态代理上。如果将动态代理实现

 

package com.itcast.aop;
//绑定操作,将指定的类通过反射生成动态代理
import java.lang.reflect.Proxy;

public class Bind {
public Object bind(Object delegate){
	//输出的是接口的全路径名称
    System.out.println("绑定操作的输出值:"+delegate.getClass().getInterfaces()[0]);
    /**通过反射生成动态代理,这里的LogHandler类是实现了InvocationHandler接口的类,
     *实现InvocationHandler接口类在北Proxy作为参数调用的时候,会调用接口中的invoke
     *方法,我们可以在invoke方法的内部进行我们的附加操作**/
	return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
			delegate.getClass().getInterfaces(), new LogHandler(delegate));
}
}

 

这里就是我们动态代理的创建了,我们将要代理的对象绑定到动态代理上,而动态代理要那个实现了InvocationHandler接口的方法类的invoke执行。那我们只能在那个invoke中做文章了。

 5、开启我们的测试类

测试下我们动态代理是否可用:

package com.itcast.aop;
//动态代理类的测试方法
public class Main {
	public static void main(String[] args) {
		Bind b = new Bind();
		IHello helloProxy = (IHello)b.bind(new HelloSpeaker2());
		try {
			helloProxy.hello("动态代理的输入参数");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

6、测试日志结果:

绑定操作的输出值:interface com.itcast.aop.IHello
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 看日志输出,被调用的方法名称是可以被输出的,你可以对所有的方法名做比对,做不同处理
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 开始我们的方法 ...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 如果你想做一个事务控制,这个地方是再好不过的地方了,开始你的事务?
Hello2 :hello 动态代理的输入参数
InvocationHandler实现类中输出传入的参数值:动态代理的输入参数
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 在这里结束你的事务!java的事务是基于代理的,这下你明白了吗?
2009-3-15 11:29:38 com.itcast.aop.LogHandler invoke
信息: 结束我们的方法...public abstract void com.itcast.aop.IHello.hello(java.lang.String) throws java.lang.Exception

上边的日志说明了我们可以输出的地方,可以做动作的位置

 6、总结下

 什么是aop,明白了没?解释起来就是“面向切面编程”,动态代理就是一把刀子,在你的程序调用的过程中切来切去。原理就是上边的动态代理。不过spring给我们封装了一下,用cglib这个jar来动态的帮我们生成每个实现类的动态代理,spring的事务控制之类的东西都是基于这个的。总的来说大家不要被穿在java外部的马甲给迷惑住了。事情的原理就是上边那个。

 

 

 

本文转载自:http://zuoqiang.iteye.com/blog/671138

共有 人打赏支持
ruyees
粉丝 3
博文 71
码字总数 0
作品 0
深圳
产品经理
有没有开源的java项目,通过web页面能控制多个定时任务的启动,修改定时时间?

最近公司写了一些定时任务,用的springframe注解方式的Scheduled,但是每次修改定时时间都很麻烦,还得改项目,打包,发到服务器,再运行,感觉无比麻烦,尤其是任务很多的时候 想从这些繁杂...

程序猿_哲 ⋅ 2014/07/04 ⋅ 8

如何插手spring启动过程

Spring提供了一种叫做BeanFactoryPostProcessor的容器扩展机制。该机制允许我们在容器实例化相应对象之前,对注册到容器的BeanDefinition所保存的信息做相应的修改。这就相当于在容器实现的第...

奋斗的欢 ⋅ 2015/03/13 ⋅ 0

Velocity模板引擎使用笔记

题记 在公司的项目中,前台界面的展现是使用Velocity模版来实现的。现在利用一些时间,把以前的使用经验记录一下,不是什么宝典秘籍,也不是什么高深理论,纯粹为一些使用经验记录,开发知识...

xiaozz ⋅ 2012/11/20 ⋅ 0

springframe源码导入到Intellij idea

今天打算把spring的最新源码4.0.x拉下来学习下,在这个过程中遇到了一些问题,记录下。 步骤:1.更新jdk版本至1.8。使用jenv来管理java开发环境,发现是一个很好用的东东, 安装jenv:brew ...

alvaDing ⋅ 2016/10/20 ⋅ 0

grails2.0M1 run-app遇到的问题.未解决..

C:UsersidorDocumentsworkspacehellohelloworld>grails run-app | Running Grails application | Error 2011-08-21 03:02:27,820 [Thread-7] ERROR context.GrailsContextLoader - Error exe......

刘文豪 ⋅ 2011/08/21 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多
用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 18分钟前 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 38分钟前 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 51分钟前 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部