`

springframe【6】

阅读更多

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外部的马甲给迷惑住了。事情的原理就是上边那个。

 

 

 

分享到:
评论

相关推荐

    用于IDEAL开发web service的springframe框架的jar包

    6. **Spring Integration**:这个模块提供了与外部系统集成的能力,如文件、数据库、JMS消息等,这对于构建复杂的分布式系统尤其有用。 在“用于IDEAL开发Web Service的springframe框架的jar包”中,"spring-...

    Spring-frame

    Spring框架的介绍,描述了和介绍了Spring常用的方法以及对Spring框架的整体介绍

    spring框架依赖

    6. **Spring ORM**:集成了流行的数据持久层框架,如Hibernate、JPA等,提供了统一的API。 7. **Spring Web**:包含用于Web应用的组件,如DispatcherServlet、ModelAndView等,支持MVC模式。 8. **Spring Test**:...

    Spring-framework-5.0.x官方源码

    6. **Spring Boot集成**:Spring 5.0.x 更好地与Spring Boot结合,简化了Spring应用的启动和配置,使得微服务开发更加便捷。 7. **Spring Data**:Spring Data项目提供了与各种数据存储的简单集成,如JPA、MongoDB...

    spring-context-support-1.0.5-API文档-中英对照版.zip

    赠送jar包:spring-context-support-1.0.5.jar; 赠送原API文档:spring-context-support-1.0.5-javadoc.jar; 赠送源代码:spring-context-support-1.0.5-sources.jar; 赠送Maven依赖信息文件:spring-context-...

    spring-framework完整源代码(spring框架源码)

    spring-framework完整源代码(spring框架源码) 完整的Spring工程源码,工程内内包括spring各模块源码 以下为spring工程源码包结构: spring-src org.springframework aop,beans,cache,context,core,dao,ejb,...

    maven+springmvc+spring+mybatis框架V1.0

    《构建基于Maven、SpringMVC、Spring和MyBatis的Web应用框架V1.0详解》 在软件开发领域,高效且稳定的架构是项目成功的关键。本篇将深入探讨如何构建一个基于Maven、SpringMVC、Spring和MyBatis的Web应用框架V1.0,...

    Spring Framework 5.1.0源码

    Spring Framework 5.1.0源码 The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform. ...

    基于JavaMail的常用类详细介绍

    6. **javax.mail.Store** 类: Store 类提供了与邮件服务器进行交互的接口,允许读取、写入和管理邮箱中的邮件。例如,通过`Store store = s.getStore("pop3")`,我们可以获取一个POP3协议的Store实例,然后通过它...

    spring 4.3.29 所有jar包

    Spring框架是Java开发中最受欢迎的轻量级框架之一,它为构建企业级应用程序提供了全面的编程和配置模型。4.3.29是Spring框架的一个稳定版本,它包含了多个核心模块和其他相关组件,以支持现代Java应用的开发。...

    兼容jdk1.8的spring.jar包

    该jar包兼容了jdk1.3到1.8,可以放心使用。

    spring-boot-2.2.x:spring-boot-2.2.x原始码解读

    Sprint Boot Spring Boot可以帮助您以最小的麻烦来创建Spring支持的生产级应用程序和服务。 它从Spring平台的角度出发,以便新老用户都能快速找到所需的信息。 您可以使用Spring Boot创建... import org.springframe

    SpringFrameWork

    6. **模块化设计**:Spring Framework是高度模块化的,开发者可以根据需要选择使用哪些模块,如Spring Core、Data Access、Web等,这有助于减少应用的复杂性和依赖性。 7. **测试支持**:Spring提供了测试工具和库...

    org.springframework.web.servlet-3.1.0.RELEASE

    是源代码,不是jar文件!!!!! /** * Holder for both Model and View in the web MVC framework. * Note that these are entirely distinct.... * both to make it possible for a controller to return both model ...

    RED5必备开发包-1

    org.springframework.core-2.5.6.A.jar

    spring-security-ad:用于 Spring Security 的 Microsoft Active Directory UserDetailsS​​ervice 和 AuthenticationProvider

    弹簧安全广告 用于基于 Microsoft Active Directory 的 AuthenticationProvider 和 UserDetailsS​​ervice 。 它适用于 Windows 2003、2008 和 2012 服务器。 项目设置 ... < groupId>org.springframe

    SpringFrameWork_file

    Spring Framework是中国最流行的Java应用程序开发框架之一,由Pivotal Software公司开发并维护。它提供了一个全面的编程和配置模型,旨在简化企业级Java应用的创建、测试和部署过程。Spring Framework的核心特性可以...

    SpringMVC基础

    SpringMVC基础 概念 SpringMVC简介 配置 添加依赖 Spring-webmvc(4.3.6)八个jar包添加进来 配置web.xml文件: 让所的/请求都交给了我DispatcherServlet,而DispatcherServlet里面需要配置一个... org.springframe

    java版 Spring Cloud搭建(二)创建Spring Boot工程-b2b2c小程序

    创建一个Spring Boot工程,这次创建比之前创建多一个步骤,在创建的时候选中web的starter,我们来创建一个web工程,在IntelliJ IDEA中创建的时候选中web,了解springcloud架构可以加求求:三五三六... org.springframe

    spring boot整合Shiro实现单点登录的示例代码

    import org.springframe; ``` 四、Shiro 的常见问题 在使用 Shiro 时,经常会遇到一些问题,例如: Q:对组的支持? A:Shiro 默认不支持对组设置权限,但可以通过扩展 Realm 来实现对组进行分配角色。 Q:是否...

Global site tag (gtag.js) - Google Analytics