走进JavaWeb技术世界10:从JavaBean讲到Spring

Java 帝国之Java bean (上)

文章转自: 刘欣 码农翻身 2016-05-27php

前言: 最近看到到spring 的bean 配置, 忽然想到可能不少人不必定知道这个叫bean的东西的前因后果, 因此就写个文章来说一下。前端

另外,上次出了开源中国抄袭事件, 为了防止转载之后个人公众号信息被故意删除, 我在文章的内容中加上了一些 刘欣(微信公众号:码农翻身) 这样的字样, 可能会形成一些烦扰, 请见谅。 java

我一手创立的Java帝国刚刚成立不久,便受到巨大的打击, 我派出去占领桌面开发的部队几乎全军覆没。 程序员

情报说微软的Visual Basic 和Borland的Delphi最近在宣传什么组件化开发, 难道就是这东西把咱们搞垮了? web

刘欣(微信公众号:码农翻身)注:参见《Java :一个帝国的诞生》和《Basic: 一个老兵的自述面试

我赶忙买了一个Visual Basic 过来研究, 果真,这个家伙确实是方便, 最让我惊叹的是:它有一个可视化编辑器 ! 算法

我只须要把一个组件(例如按钮)拖拽到可一个表单上,  设置一下属性 (颜色,字体), 再添加一个事件(onClick), 最后在onClick中写点代码就搞定了 !spring

不只如此,我本身也能够把个人代码按规范包装成一个组件, 发布出去让别人使用。sql

我看着手下给我买来的《程序员大本营》光盘, 里边居然包含了好几千个这样的组件, 有数据库浏览组件, 计时器组件, 颜色选取组件, 甚至还有收发邮件的组件......数据库

天哪, 这之后开发桌面程序岂不太简单了 !

怪不得个人Java 被打得满地找牙!

刘欣(微信公众号:码农翻身)注: 90年代末的程序员和学生估计都知道《程序员大本营》, 由csdn的创始人蒋涛制做。

我赶忙打电话给个人干将小码哥 : 小码啊, 你赶忙看看这个Visual Basic 和Delphi , 给你7天时间, 咱们Java 也得赶忙搞一套这样的东西出来。

小吗绝不含糊, 三天就给我搞了一个东西出来: Java Bean API 规范 。

我翻开一看, 哇塞, 长达114页 , 因而问他:“这是什么东西? 我要的可视化编辑器呢Visual Java 呢? ”

刘欣(微信公众号:码农翻身)注: 我下载浏览了java bean 的规范, 确实是114页

他说: “老大, 咱们是个开源的社区, 得充分利用你们的力量, 因此我没有去作像VB和Delphi那样的东西, 相反,我定义了一套规范, 只要你们按照这个规范作, 谁均可以用java 作出像VB那样的可视化开发工具出来。”

“那你说说这个java bean 究竟是什么规范?”我问。

“首先,一个java bean 其实就是一个普通的java 类, 但咱们对这个类有些要求: 

1. 这个类须要是public 的, 而后须要有个无参数的构造函数

2. 这个类的属性应该是private 的, 经过setXXX()和getXXX()来访问

3. 这个类须要能支持“事件”, 例如addXXXXListener(XXXEvent e),  事件能够是Click事件,Keyboard事件等等, 固然我们也支持自定义的事件。 

4. 咱们得提供一个所谓的自省/反射机制, 这样能在运行时查看java bean 的各类信息“

5. 这个类应该是能够序列化的, 便可以把bean的状态保存的硬盘上, 以便之后来恢复。 

“这些要求看起来也没啥啊,对程序员来讲,不就是个普通的java 类吗? 到底该怎么用? ” 

“咱们幻想一下,假设咱们的Java bean 大行其道了, 有个用户在用一个Visual Java Builder  这样的可视化开发工具, 当他用这个工具建立应用的时候, 能够选择一个叫JButton的组件, 加到一个表单上, 此时Visual Java Builder 就须要把这JButton的类经过反射给new 出来, 因此就须要一个无参数的构造函数了。”

“若是用户想去设置一下这个JButton的属性,Visual Java Builder 就须要先用自省/反射来获取这个JButton有哪些属性(经过getter/setter), 拿到之后就能够给用户显示一个属性清单了, 例如背景色, 字体 等等。用户看到后就能够设置背景色和字体了,  此时Visual Java Builder 在内部就须要调用这个Bean的setBackgroundCorlor()/setFont() 等方法, 这就是所谓的setXXXX()方法。”

“若是用户想对这个JButton编程, Visual Java Builder 仍是经过自省/反射来获取这个JButton有哪些事件, 给用户展现一个事件清单,例如click , keyboardPressed 用户能够选取一个, 而后就能够写程序对这个事件编程了。”

“但是那个序列化有什么用呢?”

“这是由于用户设计完了之后,可能关掉Visual Java Builder 啊 , 若是不经过序列化把设计好的JButton保存起来, 下次再打开Visual Java Builder , 可就什么都没有了”

我想了想, 小码哥设计的不错,仅仅用了一个简单的规范就知足了可视化编辑器的全部要求。 

"那咱们就发布这个规范吧, 我们本身先作一个可视化编辑器,给别人作个榜样, 名称我都想好了, 叫NetBean吧。"

刘欣(微信公众号:码农翻身)注:这是我杜撰的, 实际上NetBean这个名称可能和java bean 并无实际关联。 

果真不出咱们所料, Java bean 发布之后, 有力的带动了Java 的IDE市场,  开发Delphi的Borland公司 也来插了一脚,搞出了一个JBuilder, 风靡一时。 

IBM 搞了一个Visual Age for Java ,  后来摇身一变, 成了一个叫Eclipse的开放平台,超级受你们欢迎, 它反过头来把咱们的Netbean 和 JBuilder 逼的快没有活路了。 

虽然咱们玩的很欢,可是程序员根本不买帐, Java 在桌面开发市场仍是没有转机,使用Java bean 建立桌面程序的程序员少之又少, 只有部分像金融、ERP这样的领地还在坚持。   

看来是无药可救了。 

可是Java bean 何去何从 ? 丢弃掉太惋惜了,   我和小码哥商量了一下, 咱们以为:既然咱们Java在统治了服务器端的编程, 仍是在那里想一想办法吧......

上一篇提到Java bean 的规范虽然定义的不错, 但却没有得到意料中的成功, 尤为是Java帝国所期待的桌面开发组件化市场上。 

我和小码哥多么期待CSDN也能出一期《程序员大本营》, 里边包含成千上万的java bean 组件啊。

不要幻想了, 赶忙把java bean 应用在服务器端才是正事。

JSP + Java Bean

小码哥建议先用在jsp上试试,  能够用java bean 来封装业务逻辑,保存数据到数据库, 像这样:

(微信公众号"码农翻身"注: 这其实叫作JSP Model 1 )

其中jsp 直接用来接受用户的请求, 而后经过java bean 来处理业务, 具体的使用方法是:

这就能把HTTP request中的全部参数都设置到 user 这个java bean 对应的属性上去。 

若是想偷懒, 还能够这样:

固然要保证 http request中的参数名和 java bean 中的属性名是同样的。 

这个叫作JSP Model 1 的模型受到了不少Java程序员的欢迎 ,  由于他们的应用规模都很小, 用Model 1 使得开发很快速。

实际上, 这种方式和微软帝国的asp , 以及和开源的php 几乎同样。 

但很快就有人来找我抱怨了, 说他们的项目中使用了Model 1 致使整个系统的崩溃。 

他说: “你知道吗? 咱们的系统中有好几千个jsp, 这些jsp互相调用(经过GET/POST), 到了最后调用关系无人能搞懂。 ”

其实咱们已经预料到了, 小码哥对此有个形象的比喻:意大利面条

这几千个JSP 就像这碗面条同样,搅在一块儿, 根本理不清楚。

为了解决这个问题,小码哥又推出了 :JSP Model 2 ,    这是个模型真正的体现了Model-View-Controller的思想:

Servlet 充当Controller ,  jsp 充当 View 

Java bean 固然就是Model 了!

业务逻辑, 页面显示, 和处理过程作了很好的分离。 

基于这个模型的扩展和改进,  不少Web开发框架开始如雨后春笋同样出现, 其中最著名的就是Struts, SpringMVC 了。

Java Web开发迅速的繁荣了。 

咱们再一次体会到了开放的好处 !

Enterprise Java bean

可是好景不长, 自从Java帝国统治了所谓的“企业级应用”开发领地, 各类各样的游行和抗议层出不穷:

“咱们要分布式”

“咱们要安全”

“咱们要事务”
“咱们要高可用性”

“......”

帝国分析了一下, 其实这些程序员的诉求能够归结为:

“咱们只想关注咱们的业务逻辑, 咱们不想, 也不该该由咱们来处理‘低级’的事务, 多线程,链接池,以及其余各类各类的‘低级’API, 此外Java帝国必定得提供集群功能, 这样咱们的一台机器死机之后,整个系统还能运转。 ”

咱们不能坐着无论, 企业级应用是咱们的命根子。

小码哥彻夜工做, 最终拿出了一个叫作J2EE的东西, 像Java bean 同样, 这仍是一个规范, 可是比Java bean 复杂的多, 其中有:

JDBC:  Java 数据库链接, 没有数据库的支持怎么能叫企业级应用?

JNDI :  Java 命名和目录接口, 经过一个名称就能够定位到一个数据源, 连jdbc链接都不用了

RMI:  远程过程调用,  让一个机器上的java 对象能够调用另一个机器上的java 对象 , 大家不是要分布式吗?

JMS :   Java 消息服务,  可使用消息队列了, 这不是企业级应用很是须要的吗?

JTA:  Java 事务管理, 支持分布式事务, 能在访问、更新多个数据库的时候,仍然保证事务, 仍是分布式。

Java mail : 收发邮件也是必不可少的啊。

刘欣(微信公众号号:码农翻身)注:  J2EE 后来改为了Java EE。

固然还有最最最重要的升级, 小码哥把java bean 变成了 Enterprise Java bean , 简称 EJB

小码哥宣称: 

使用了EJB, 你就能够把精力只放在业务上了, 那些烦人的事务管理, 安全管理,线程 通通交给容器(应用服务器)来处理吧。 

咱们还提供了额外的福利, 只要你的应用服务器是由多个机器组成的集群, EJB就能够无缝的运行在这个集群上, 你彻底不用考虑一个机器死掉了应用该怎么办。咱们都帮你搞定了。 

使用Session Bean , 能够轻松的处理你的业务。

使用实体Bean (Entity bean ) , 你和数据库打交道会变得极为轻松, 甚至sql 都不用写了。

使用消息驱动Bean(Message Driven bean ) , 你能够轻松的和一个消息队列链接, 处理消息。

听起来很美好是否是? 

企业级开发领地的程序员们欢呼雀跃, 坐上了J2EE这条船,彷佛一会儿高贵起来, 开始鄙视微软的ASP, 开源的PHP, Python 等“不入流”的语言了 。

Weblogic , Websphere等符合J2EE规范的应用服务器趁势而上, 摇旗呐喊, 仿佛一个新的时代要来临了, 固然他们在背后一直闷声发大财。 

Sring

有句古话是对的, 捧的越高, 跌的越惨。 

很快,大部分的程序员就发现, 美好的前景并无实现, EJB中用起来极为繁琐和笨重, 性能也很差, 为了得到所谓的分布式,反而背上了沉重的枷锁。 

实体Bean很快没人用了, 就连简单的无状态Session bean 也被你们所诟病, 其中一条罪状就是“代码的侵入性”。

也是, 小码哥定义EJB的时候没考虑那么多,程序员在定义一个Session bean的时候,须要写一大堆和业务彻底没有关系的类。 

还须要被迫实现一些根本不该该实现的接口及其方法: 

为了哪怕一点点业务逻辑, 咱们都得写这么多无用的代码 ! 程序员们出离愤怒了!

他们发起了一场叫作POJO (Plain Old Java Object)的运动, 高唱这POJO之歌, 要求咱们整改。 

他们但愿这个样子:

public class HelloworldBean{

    public String hello(){

        return "hello world"

    }

}

与此同时,他们还过度的要求保留事务了, 安全了这些必备的东西。 

程序员确实很差伺候,   可是咱们已经被Weblogic, Websphere这些大佬们“绑架”, 想改动谈何容易 !

2002年, 小码哥看到了Rod Johnson写的一本书《Expert one on one J2EE development withoutEJB》 , 赶忙跑来找我:

“老大, 坏了坏了, 你快看看这本书吧, 这个叫Rod的家伙写的这本书直击咱们的命门,这厮要搞without EJB”

(微信公众号"码农翻身"注: 虽然这本书翻译的不好,但因为是spring的开山之做,仍是值得读一下, 最好中英文对照)

岂止是without EJB,  他还“偷偷的”推出了一个叫什么Spring的框架, 已经迅速的流行开了。

Spring 框架顺应了POJO的潮流, 提供了一个spring 的容器来管理这些POJO, 好玩的是也叫作bean 。

看来咱们的java bean 走了一圈又回到了原点。 

对于一个Bean 来讲,若是你依赖别的Bean , 只须要声明便可, spring 容器负责把依赖的bean 给“注入进去“, 起初你们称之为控制反转(IoC)

后来 Martin flower 给这种方式起来个更好的名字,叫“依赖注入”。

若是一个Bean 须要一些像事务,日志,安全这样的通用的服务, 也是只须要声明便可, spring 容器在运行时可以动态的“织入”这些服务, 这叫AOP。 

后来我和小码哥商量, 咱们EJB也学习Spring , 简化开发和配置, 可是为时已晚, Spring 已经成为事实上的标准了!程序员已经被spring 拉走了!

不过令咱们欣慰的是, spring和spring mvc极大的增长了咱们对web开发领地的统治力, java 帝国更增强盛了。 

(全文完)

Spring 的本质系列(1) -- 依赖注入

转自: 刘欣 码农翻身 2016-06-25

转载 码农翻身微信公众号 2016-06-25 刘欣 《Spring 的本质系列(1) -- 依赖注入》

1. 对象的建立

       面向对象的编程语言是用类(Class)来对现实世界进行抽象, 在运行时这些类会生成对象(Object)。 
       固然,单独的一个或几个对象根本没办法完成复杂的业务, 实际的系统是由千千万万个对象组成的, 这些对象须要互相协做才能干活,例如对象A调用对象B的方法,那必然会提出一个问题:对象A怎么才能得到对象B的引用呢?
       最简单的办法无非是: 当对象A须要使用对象B的时候, 把它给new 出来 ,这也是最经常使用的办法, java 不就是这么作的?例如:  Apple a = new Apple();
       后来业务变复杂了, 抽象出了一个水果(Fruit)的类, 建立对象会变成这个样子:
       Fruit f1 = new Apple();
       Fruit f2 = new Banana();
       Fruit f3 = ......
      很天然的,相似下面的代码就会出现:

       这样的代码若是散落在各处,维护起来将会痛苦不堪, 例如你新加一个水果的类型Orange, 那得找到系统中全部的这些建立Fruit的地方,进行修改, 这绝对是一场噩梦。
 解决办法也很简单, 前辈们早就总结好了:工厂模式 

       工厂模式,以及其余模式像抽象工厂, Builder模式提供的都是建立对象的方法。这背后体现的都是“封装变化”的思想。这些模式只是一些最佳实践而已: 起了一个名称、描述一下解决的问题、使用的范围和场景,码农们在项目中还得本身去编码实现他们。

2. 解除依赖

        咱们再来看一个稍微复杂一点, 更加贴近实际项目的例子:
        一个订单处理类,它会被定时调用:  查询数据库中订单的处理状况, 必要时给下订单的用户发信。

        看起来也没什么难度, 须要注意的是不少类一块儿协做了, 尤为是OrderProcessor , 它依赖于OrderService 和 EmailService这两个服务,它获取依赖的方式就是经过单例方法。
        若是你想对这个process方法进行单元测试--这也是不少优秀的团队要求的-- 麻烦就来了。 
        首先OrderService 确实会从真正的数据库中取得Order信息,你须要确保数据库中有数据, 数据库链接没问题,实际上若是数据库链接Container(例如Tomcat)管理的, 你没有Tomcat很难创建数据库链接。
       其次这个EmailService 真的会对外发邮件, 你可不想对真正的用户发测试邮件,固然你能够修改数据库,把邮件地址改为假的,但那样很麻烦, 而且EmailService 会抛出一堆错误来,很不爽。
       全部的这些障碍, 最终会致使脆弱的单元测试: 速度慢, 不可重复,须要手工干预,不能独立运行。
       想克服这些障碍, 一个可行的办法就是不在方法中直接调用OrderService和EmailService的getInstance()方法, 而是把他们经过setter方法传进来。

       经过这种方式,你的单元测试就能够构造一个假的OrderService 和假的EmailService 了。
       例如OrderService 的冒牌货能够是MockOrderService , 它能够返回你想要的任何Order 对象, 而不是从数据库取。MockEmailService 也不会真的发邮件, 而是把代码中试图发的邮件保存下来, 测试程序能够检查是否正确。
       你的测试代码多是这样的:

        固然, 有经验的你立刻就会意识到: 须要把OrderService 和 EmailService 变成 接口或者抽象类, 这样才能够把Mock对象传进来。 
        这其实也遵循了面向对象编程的另一个要求: 对接口编程, 而不是对实现编程。

3. Spring 依赖注入

        啰啰嗦嗦说了这么多, 快要和Spring扯上关系了。
       上面的代码其实就是实现了一个依赖的注入,把两个冒牌货注入到业务类中(经过set方法), 这个注入的过程是在一个测试类中经过代码完成的。
       既然能把冒牌货注入进去,  那毫无疑问,确定也能把一个正经的类安插进去, 由于setter 方法接受的是接口,而不是具体类。

       用这种方式来处理对象之间的依赖, 会强迫你对接口编程, 好处显而易见。 
       随着系统复杂度的增加, 这样的代码会愈来愈多, 最后也会变得难于维护。 
       能不能把各个类之间的依赖关系统一维护呢?
       能不能把系统作的更加灵活一点,用声明的方式而不是用代码的方式来描述依赖关系呢?
       确定能够, 在Java 世界里,若是想描述各类逻辑关系, XML是不二之选:

        这个xml 挺容易理解的, 可是仅仅有它还不够, 还缺一个解析器(假设叫作XmlAppContext)来解析,处理这个文件,基本过程是:
         0. 解析xml, 获取各类元素
         1. 经过Java反射把各个bean 的实例建立起来: com.coderising.OrderProcessor   , OrderServiceImpl, EmailServiceImpl. 
         2. 仍是经过Java反射调用OrderProcessor的两个方法:setOrderService(....)  和 setEmailService(...) 把orderService , emailService 实例 注入进去。
        应用程序使用起来就简单了:
        XmlAppContext ctx = new XmlAppContext("c:\bean.xml");
        OrderProcessor op = (OrderProcessor) ctx.getBean("order-processor");
        op.process();
        其实Spring的处理方式和上面说的很是相似, 固然Spring 处理了更多的细节,例如不只仅是setter方法注入, 还能够构造函数注入,init 方法, destroy方法等等, 基本思想是一致的。

       既然对象的建立过程和装配过程都是Spring作的, 那Spring 在这个过程当中就能够玩不少把戏了, 好比对你的业务类作点字节码级别的加强, 搞点AOP什么的, 这都不在话下了。 

4. IoC vs DI

        “不要给咱们打电话,咱们会打给你的(don‘t call us, we‘ll call you)”这是著名的好莱坞原则。
        在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项目彻底控制,演员只能被动式的接受公司的差使,在须要的环节中,完成本身的演出。
        这和软件开发有必定的类似性, 演员们就像一个个Java Object, 最先的时候本身去建立本身所依赖的对象,   有了演艺公司(Spring容器)的介入,全部的依赖关系都是演艺公司搞定的, 因而控制就翻转了 
        Inversion of Control, 简称IoC。 可是IoC这个词不能让人更加直观和清晰的理解背后所表明的含义, 因而Martin Flower先生就创造了一个新词 : 依赖注入 (Dependency Injection,简称DI),  是否是更加贴切一点?

Spring本质系列(2)-AOP

原创: 刘欣 码农翻身 2016-06-30

   听说有些词汇很是热门和神奇, 若是你常常把它挂在嘴边,就能让本身功力大涨, 能够轻松找到理想的高薪的工做,这些词就包括上一篇文章(《Spring本质系列(1) --依赖注入》)中聊过的IoC 和 DI, 也包括今天要聊的AOP。
       AOP(Aspect Oriented Programming)就是面向切面的编程, 为何是面向切面, 而不是面向对象呢?

1. 问题来源

      咱们在作系统设计的时候,一个很是重要的工做就是把一个大系统作分解, 按业务功能分解成一个个低耦合、高内聚的模块,就像这样:

       可是分解之后就会发现有些颇有趣的东西, 这些东西是通用的,或者是跨越多个模块的:
       日志: 对特定的操做输出日志来记录
       安全:在执行操做以前进行操做检查
       性能:要统计每一个方法的执行时间
       事务:方法开始以前要开始事务, 结束后要提交或者回滚事务
       等等....
       这些能够称为是非功能需求, 但他们是多个业务模块都须要的, 是跨越模块的, 把他们放到什么地方呢?
       最简单的办法就是把这些通用模块的接口写好, 让程序员在实现业务模块的时候去调用就能够了,码农嘛,辛苦一下也没什么。

      这样作看起来没问题, 只是会产生相似这样的代码:

      这样的代码也实现了功能,可是看起来很是的不爽, 那就是日志,性能,事务 相关的代码几乎要把真正的业务代码给淹没了。
      不只仅这一个类须要这么干, 其余类都得这么干, 重复代码会很是的多。
      有经验的程序员还好, 新手忘记写这样的非业务代码简直是必然的。

2. 设计模式:模板方法

      用设计模式在某些状况下能够部分解决上面的问题,例如著名的模板方法:

       在父类(BaseCommand)中已经把那些“乱七八糟“的非功能代码都写好了, 只是留了一个口子(抽象方法doBusiness())让子类去实现。
       子类变的清爽, 只须要关注业务逻辑就能够了。
       调用也很简单,例如:
       BaseCommand  cmd = ...  得到PlaceOrderCommand的实例...
       cmd.execute();
       可是这样方式的巨大缺陷就是父类会定义一切: 要执行哪些非功能代码, 以什么顺序执行等等
      子类只能无条件接受,彻底没有反抗余地。
       若是有个子类, 根本不须要事务, 可是它也没有办法把事务代码去掉。

3. 设计模式:装饰者

      若是利用装饰者模式, 针对上面的问题,能够带来更大的灵活性:

       如今让这个PlaceOrderCommand 可以打印日志,进行性能统计
       Command cmd = new LoggerDecorator(
              new PerformanceDecorator(
                  new PlaceOrderCommand()));
       cmd.execute();

       若是PaymentCommand 只须要打印日志,装饰一次就能够了:
       Command cmd = new LoggerDecorator(
              new PaymentCommand());
       cmd.execute();
       可使用任意数量装饰器,还能够以任意次序执行(严格意义上来讲是不行的), 是否是很灵活? 

4. AOP

       若是仔细思考一下就会发现装饰者模式的不爽之处:
       (1)  一个处理日志/性能/事务 的类为何要实现 业务接口(Command)呢?
       (2) 若是别的业务模块,没有实现Command接口,可是也想利用日志/性能/事务等功能,该怎么办呢?

       最好把日志/安全/事务这样的代码和业务代码彻底隔离开来,由于他们的关注点和业务代码的关注点彻底不一样 ,他们之间应该是正交的,他们之间的关系应该是这样的:

       若是把这个业务功能当作一层层面包的话, 这些日志/安全/事务 像不像一个个“切面”(Aspect) ?
       若是咱们能让这些“切面“能和业务独立,  而且可以很是灵活的“织入”到业务方法中, 那就实现了面向切面编程(AOP)!

5. 实现AOP

       如今咱们来实现AOP吧, 首先咱们得有一个所谓的“切面“类(Aspect), 这应该是一个普通的java 类,不用实现什么“乱七八糟”的接口。以一个事务类为例:

       咱们想达到的目的只这样的: 对于com.coderising这个包中全部类的execute方法, 在方法调用以前,须要执行Transaction.beginTx()方法, 在调用以后, 须要执行Transaction.commitTx()方法。
       暂时停下脚步分析一下。
      “对于com.coderising这个包中全部类的execute方法” , 用一个时髦的词来描述就是切入点(PointCut) , 它能够是一个方法或一组方法(能够经过通配符来支持,你懂的)
      ”在方法调用以前/以后 , 须要执行xxx“ , 用另一个时髦的词来描述就是通知(Advice)
       码农翻身认为,PointCut,Advice 这些词实在是不直观, 其实Spring的做者们也是这么想的 :  These terms are not Spring-specific… unfortunately, AOP terminology is not particularly intuitive; however, it would be even more confusing if Spring used its own terminology.
       固然,想描述这些规则, xml依然是不二之选:

       注意:如今Transaction这个类和业务类在源代码层次上没有一点关系,彻底隔离了。隔离是一件好事情, 可是立刻给咱们带来了大麻烦 。
       Java 是一门静态的强类型语言, 代码一旦写好, 编译成java class 之后 ,能够在运行时经过反射(Reflection)来查看类的信息, 可是想对类进行修改很是困难。 
       而AOP要求的偏偏就是在不改变业务类的源代码(其实大部分状况下你也拿不到)的状况下, 修改业务类的方法, 进行功能的加强,就像上面给全部的业务类增长事务支持。
      为了突破这个限制,你们能够说是费尽心机, 如今基本是有这么几种技术:
      (1) 在编译的时候, 根据AOP的配置信息,悄悄的把日志,安全,事务等“切面”代码 和业务类编译到一块儿去。
      (2) 在运行期,业务类加载之后, 经过Java动态代理技术为业务类生产一个代理类, 把“切面”代码放到代理类中,  Java 动态代理要求业务类须要实现接口才行。
      (3) 在运行期, 业务类加载之后, 动态的使用字节码构建一个业务类的子类,将“切面”逻辑加入到子类当中去, CGLIB就是这么作的。
      Spring采用的就是(1) +(2) 的方式,限于篇幅,这里再也不展开各类技术了, 无论使用哪种方式, 在运行时,真正干活的“业务类”其实已经不是原来单纯的业务类了, 它们被AOP了 !、

微信公众号【黄小斜】大厂程序员,互联网行业新知,终身学习践行者。关注后回复「Java」、「Python」、「C++」、「大数据」、「机器学习」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「笔试」、「面试」、「面经」、「计算机基础」、「LeetCode」 等关键字能够获取对应的免费学习资料。

                     

相关文章
相关标签/搜索