原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://tonyaction.blog.51cto.com/227462/42039
Spring为Java大地带来了一阵春风,它作为一个优秀的轻量级企业应用开发框架,能够大大简化企业应用开发的复杂性。
Spring以反向控制和AOP这两样先进的设计理念为基础,统一了应用对象的查找、配置和生命周期的管理,分离了业务与基础服务中的不同关注
点,开发人员可以基于简单Java对象轻松的实现与EJB同样强大的功能。
AOP经常被定义为一种编程技术,用来在系统中提升业务的分离,系统有很多组件组成,每一组件负责一部分功能。 然而,这些组件也经常带有一些除了核心功能之外的附带功能。系统服务如日志、事务管理和安全经常融入到一些其他功能模块中。这些系统服务通常叫做交叉业 务,这是因为,它们总是分布在系统的很多组件中,通过将这些业务分布在多个组件中,你给你的代码引入了双重复杂性。
           ---摘自《Spring in Action》
今天我给大家介绍一下Spring是如何实现AOP技术的,这里需要一些反射和代理的知识,大家可以看我以前的 文章,里面有关于反射代理的讲解和代码演示,我们可以通过AOP技术在目标对象不知情的情况之下做一些参数的验证或者一些日志记录,而目标对象并不用操心 我们对他作了什么(其实他根本就不知道我们做了什么)因为所有的一切我们是在目标对象的代理类中实现的,下面我给大家讲解一下我所理解的AOP技术。
讲解AOP时,我还是使用我关于代理那篇文章中的例子:
首先需要一个接口
   interface Foo
   {
 public String printMessage(String message);
   }
一个实现这个接口的类
public class FooClass implements Foo {
 public String printMessage(String message)
 {
  
  return "This is Object FooClass~!" + message;
 }
}
一个实现了InvocationHandler接口的类(这个类用于实现面向切面)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;
public class MyInvocationHandler implements InvocationHandler {
private Object fooClass;
 public MyInvocationHandler(Object fooClass) {
  
  this.fooClass = fooClass;
 }
public Object invoke(Object arg0, Method arg1, Object[] arg2)throws Throwable
 {
  BasicConfigurator.configure();
  Log log = LogFactory.getLog(MyInvocationHandler.class);
  log.info("This is " + MyInvocationHandler.class.getName() + "You want invoke "+ arg1.getName());
  
  return arg1.invoke(fooClass,arg2);
 }
}
一个实现了FactoryBean接口的类(FactoryBean接口在Spring中用于得到一个ProxyObject对象)
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import org.springframework.beans.factory.FactoryBean;
public class MyFactoryBean implements FactoryBean {
private String target = null;
private String interf = null;
 
  
 
 public Object getObject() throws Exception //在这个方法中我们通过java的代理技术得到了一个代理类,所有的参数都是通过         //XML文件传递给BeanFactory的所以我们需要一个BeanFactory的对象和一个启动运         //行类
 {
  Class[] interClass = new Class[]{Class.forName(interf)};
  Object objTarget = Class.forName(target).newInstance();
  Object objProxy =Proxy.newProxyInstance(Foo.class.getClassLoader(),interClass,new
          MyInvocationHandler(objTarget));
  
  return objProxy;
 }
public Class getObjectType() {
  
  return null;
 }
public boolean isSingleton() {
  
  return false;
 }
public String getTarget() {
  return target;
 }
public void setTarget(String target) {
  this.target = target;
 }
public String getInterf() {
  return interf;
 }
public void setInterf(String interf) {
  this.interf = interf;
 }
}
一个启动运行类,其中有BeanFactory对象的实例
import java.util.ArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.BasicConfigurator;//使用了log4j.properties文件,如果不实用这个文件可以使用这个包
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;//如果要使用绝对路径读取*.XML文件可以使用这个包

public class MainClass {

 public static void main(String[] args) throws Exception
 {
  //BasicConfigurator.configure();
  
  Log log = LogFactory.getLog(MainClass.class);//实例一个Log对象
  BeanFactory factory = new XmlBeanFactory(new ClassPathResource("/applicationContext.xml"));
  //通过XmlBeanFactory来读取applicationContext.xml文件
  
  Foo foo =(Foo)factory.getBean("bean");//此时Spring会自动调用factory.getObject方法,返回一个对象
  //此时的factory.getBean("bean")是如何的一个Foo对象的呢?他又是如何知道应该调用MyFactoryBean.getObject()
  //的方法呢?我给大家简单讲解一下BeanFactory类的getBean方法的工作原理,首先我们在实例化BeanFactory的对象的时候
  //会读取一个XML文件此时XML文件中的所有内容都将存到factory 对象的内部,每当我们调用factory.getBean("xxx")时
  //它会在自身内部寻找<bean>标签中id属性为"xxx"的bean将其注入并且实例化。

log.info(foo.printMessage("Hello I'm Tony"));//调用这个对象的方法
  
 }
  
}
applicationContext.xml文件的全部内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "[url]http://www.springframework.org/dtd/spring-beans.dtd[/url]">

<beans>
 <bean id="bean" class="MyFactoryBean">
  <property name="target">
   <value>FooClass</value>
  </property>
 
  <property name="interf">
   <value>Foo</value>
  </property>
 </bean>
</beans>
log4j.properties文件的全部内容
log4j.rootLogger=info,sysout
log4j.appender.sysout=org.apache.log4j.ConsoleAppender
log4j.appender.sysout.layout=org.apache.log4j.SimpleLayout

applicationContext.xml和log4j.properties放在classpath路径下,ClassPathResource和LogFactory会自动找到了

本文出自 “绝缘材料” 博客,请务必保留此出处http://tonyaction.blog.51cto.com/227462/42039

转载于:https://blog.51cto.com/4925054/1059948

Spring从菜鸟到高手(一)实现AOP的基本原理相关推荐

  1. Spring从菜鸟到高手(四)(上)使用JdbcTemplate类实现用户登陆验证、批量更新

    标签:Spring java JdbcTemplate Spring从菜鸟到高手 绝缘材料 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.ht ...

  2. Spring从菜鸟到高手(二)AOP的真正实现

    经过了前面一章的学习大家基本理解了SpringAOP的简单工作原理,但是那只是最基本的一些操作,Spring的设计师们知道我们不想在诸如得到一个代理类.需要实现哪些接口 这些琐碎的事情上牵扯过多的经历 ...

  3. 从菜鸟到高手演变-----Java学习方法

    前段时间逛论坛,总会有很多新手很迷茫,问到:到底该怎么学好Java,这个问题很重要,尤其对于像我们这样大多数都是靠自学的人来说,找到一个好的学习方法至关重要!于是乎,我就给大家回答了很多,突然间想到了 ...

  4. Java之美[从菜鸟到高手演变]系列之博文阅读导航

    随着博文越来越多,为博客添加一个导航很有必要!本博客将相继开通Java.CloudFoundry.Linux.Ruby等专栏,都会设立目录,希望读者朋友们能更加方便的阅读! 在阅读的过程中有任何问题, ...

  5. 全局变量和局部变量的区别_值得收藏!8大技巧,带你了解菜鸟和高手的区别!...

    对于Python编程者而言,或许大家都认为Python是非常简单易学的,在学习一段时间的Python之后,都认为自己的Python编程水平已经非常好了,但是python编程绝对不是简单的几句语法就可以 ...

  6. 干货 | 大数据人工智能领域从菜鸟到高手晋级指南

    作者 | 王明哲.王存光 校对 | 丁楠雅 本文长度为5600字,建议阅读10分钟 本文为你剖析当下的时代背景,为在大数据江湖中修炼的行者提供升级建议. 我们身处一个"技术爆炸"和 ...

  7. VMware View 5.0从菜鸟到高手系列 10 –远程图形工作站配置篇

    本文档依照PCoIP设备供应商丽台(Leadtek)提供的零客户机VP200P以及PCoI卡VP200H为例,为了介绍整个安装步骤.以下配置在VMware view 4.5中安装,但在更新的版本中如V ...

  8. [从菜鸟到高手演变]之智力题【史上最全】 (转)

    原文地址:http://blog.csdn.net/zhangerqing/article/details/8138296 PS:在一次偶然的机会中,发现了这篇文章.希望大家能开动脑经. 智力题,每个 ...

  9. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

最新文章

  1. gil php,网络编程之多线程——GIL全局解释器锁
  2. 深度学习核心技术精讲100篇(八十)-脏数据如何处理?置信学习解决方案
  3. RabbitMQ延迟消息的极限是多少?
  4. IOC操作Bean管理XML方式(有参构造注入属性)
  5. 知网直接下载pdf文档
  6. web 服务器 内存 影响_工业环境软件套件 CODESYS web 服务器被曝严重的RCE漏洞
  7. c语言cin cou头文件,c+第五次实验
  8. 漫画:应用程序被拖慢?罪魁祸首是 Log4j!
  9. L1-019. 谁先倒-PAT团体程序设计天梯赛GPLT
  10. 2019年软考程序员考试大纲
  11. 官宣,港珠澳大桥终于来了
  12. 一维搜索之黄金分割法
  13. 小心 transmittable-thread-local 的这个坑
  14. R语言学习之深圳市空气质量分析
  15. 故事:两只老虎的悲惨结局
  16. 2023最新WSL搭建深度学习平台教程(适用于Docker-gpu、tensorflow-gpu、pytorch-gpu)
  17. C语言|博客作业10
  18. Lenovo 拯救者15ISK硬件升级
  19. 一周肝出Linux之远程服务详解(ssh远程登录、scp远程复制、sftp安全下载、TCP Wrappers访问控制)
  20. 靶机渗透练习43-Lord Of The Root

热门文章

  1. SQL联合主键 查重
  2. Android学习第十三天----ScrollView
  3. 以孩子兄弟链表为存储结构,请设计递归算法求树的高度
  4. 诗与远方:无题(九十二)
  5. 诗与远方:无题(十八)
  6. idea 创建 spring 配置文件
  7. 为什么要使用数据连接池
  8. LabVIEW连接MySQL数据库
  9. ajax请求头cookies中传递sid,跨域请求单点登录,登录成功,但是在controller中获取的cookie与浏览器中不一致,请大神指点一二。^_^...
  10. 如何查看文件的字符集