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

立创EDA标准版迁移到专业版全流程:3D模型与高级布线实战指南 在电子设计自动化(EDA)工具链中,PCB设计软件的选择直接决定项目效率与制造质量。随着电路复杂度提升,从基础版向专业级平台的迁移成为许多硬件工程师的必经之路。专业版基于全新架构重构,在文件格式、渲染引擎与布线规则上均有本质升级,支持更精细的3D模型管理、差分对等长布线及制造文件输出。理解两代工具的底层差异,掌握工程备份、封装整理与数据转换原理,能显著降低迁移风险。在实际工程中,迁移后解锁的STEP模型导出可帮助结构工程师进行装配干涉检查,而高级布线规则则保障高速信号完整性。从云端工程导入到本地文件转换,系 阅读详情

前言: 最近看到到spring 的bean 配置, 突然想到可能很多人不一定知道这个叫bean的东西的来龙去脉, 所以就写个文章来讲一下。

 

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

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

 

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

 

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

 

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

 

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

 

不仅如此,我自己也可以把我的代码按规范包装成一个组件, 发布出去让别人使用。

 

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

 

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

 

怪不得我的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帝国所期待的桌面开发组件化市场上。 

 

我和小码哥多么期待优快云也能出一期《程序员大本营》, 里边包含成千上万的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了 !

litespring:从零造spring--刘欣课程 litespring 学习从零造Spring 立即下载

相关推荐

20240128 C#与SCPI协议实战:轻量级仪器控制库ScpiNet应用指南

本文详细介绍了轻量级C#库ScpiNet在仪器控制中的应用。相较于传统的NI-VISA,ScpiNet无需安装庞大运行时,通过纯C#实现直接与USB或以太网设备通信,支持跨厂商SCPI仪器。文章提供了从快速连接到实战封装、错误处理的完整指南,帮助开发者构建简洁高效的自动化测试系统。

h9j8k7l6m5n的博客 546

Spring中JavaBean的生命周期及模式

在Spring框架中,JavaBean的背景可以追溯到Java语言的发展和面向对象编程的原则。JavaBean作为一种特定的编程规范和约定,被引入到Spring框架中,以实现更加灵活和可扩展的开发方式。在Spring框架中,JavaBean是一个普通的Java类,遵循一些特定的_命名和属性规范1. 私有的成员变量:JavaBean类中的属性通常是私有的,以保护数据,同时提供公共的getter和setter方法来访问和修改属性的值。

GitHub质检员 454

【Proteus】NE555纯硬件实现LED呼吸灯效果,附源文件,效果展示

本设计通过NE555与三极管的巧妙配合,仅用基础元件实现了呼吸灯效果。核心在于利用RC积分电路将PWM信号转换为控制电压,并通过负反馈动态调节占空比。Proteus仿真验证了方案的可行性,读者可进一步优化参数或扩展功能,探索更多硬件设计可能性。

2201_75797484的博客 2979

一篇文章了解Java spring中bean的生命周期!

会将Bean解析成Spring内部的BeanDefinition结构;将spring.xml中的标签转换成BeanDefinition结构有点类似于XML解析。

lz17267861157的博客 755

基于AIS动态数据与AI结合得经纬度标示算法

港口船舶智能标注系统 本系统通过结合摄像头视频流和AIS船舶动态数据,利用AI技术实现船舶实时标注功能。系统架构包括视频流处理、AIS数据解析、船舶检测匹配和坐标映射转换等模块。关键技术步骤: AIS数据获取:通过本地接收机或网络API获取船舶位置、航速等信息 AI目标检测:采用YOLOv8等模型识别视频中的船舶 船舶匹配算法:通过位置投影或运动轨迹匹配视频目标与AIS数据 坐标映射:使用相机标定技术将经纬度转换为图像坐标 实时标注:在视频画面上叠加船名、位置等关键信息 应用场景包括港口监控、智能海事管理和

qianbo042311的博客 1808

STM32实战:电容触摸屏I2C转USB HID设备全解析

本文详细解析了基于STM32的电容触摸屏I2C转USB HID设备实现方案。通过硬件选型、协议分析和代码实现,展示了如何将GT911触摸屏数据转换为标准USB HID协议,并提供了关键调试经验与性能优化技巧,为智能家居控制面板等应用提供高性价比解决方案。

weixin_42548829的博客 320

spring 依赖注入_【Spring基础】JavaBean的配置与依赖注入

0 前言Spring的核心就是提供了一个IoC(Inversion of Control)容器,它可以管理所有轻量级的JavaBean组件,提供的底层服务包括组件的生命周期管理、配置和组装服务、AOP支持,以及建立在AOP基础上的声明式事务服务等。本本主要展示IoC容器对JavaBean装配,以及依赖的注入的几种方式。看本文之前请务必学习JAVA基础。1 传统的实现方式先来看下面这个例子:clas...

weixin_39632693的博客 297

maya导入导出bvh 自动 脚本

maya打开bvh脚本

jacke121的专栏 1550

关于《码农翻身》一书的读后感以及自己的一些拙见汇总

《码农翻身》读后感,以及自己的一些总结

产品经理克星(狗头) 1976

mindie部署qwen3-8b

2. 确认目录文件权限是否如下所示,若存在不匹配项,则参考以下命令修改权限。否则要stop容器之后重新start,重新从《以下是在容器中的操作》开始操作。ctrl +d 让命令停止之后,需要等待一段事件让其释放,否则还会有占用。1. 若安装路径为默认路径,执行如下命令,进入MindIE安装目录。# 配置CANN环境,默认安装在/usr/local目录下。3. 运行以下命令初始化各组件环境变量,并开启日志打印。如果报错,可能有些线程没法去除,删除容器重新操作。# 配置模型仓环境变量。以下是在容器中的操作。

andeyeluguo的博客 1035

无线充电Qi协议正向通信FSK的解调设计

常见的FSK解调方法是使用频率锁相环(PLL)来跟踪输入信号中的频率变化。PLL根据输入信号的频率变化来生成数字信号,从而实现FSK信号的解调。本文将详细介绍无线充电Qi协议正向通信FSK的解调设计,并提供相应的源代码。在上述示例代码中,我们首先定义了FSK解调的参数,包括采样率、载波频率、每个比特的持续时间和比特判定阈值。最后,通过比较滤波后的信号与比特判定阈值,我们将解调后的数字数据转换为0和1的序列。请注意,上述代码仅为示例,实际的解调设计可能需要根据具体的应用场景和系统要求进行调整和优化。

IunScala的博客 2443

码农翻身:从JavaBean到Spring

https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513115&idx=1&sn=da30cf3d3f163d478748fcdf721b6414&scene=21#wechat_redirect https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&am...

mhHao的博客 419

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

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

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看喜欢的话麻烦点下Star哈文章首发于我的个人博客:www.how2playlife.com本×××术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。该系列博文会告...

weixin_31233537的博客 155

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

javabean和一般意义上的java类有何区别_走进JavaWeb技术世界10:从JavaBean讲到Spring...

Java BeanJava语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库。举个例子,假如有人要用Java实现一个单向链表类,可能会这样写...

weixin_31679307的博客 3840

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

spring mvc jsp页面传对象给controller 为空_走进JavaWeb技术世界10:从JavaBean讲到Spring

Java BeanJava语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库。举个例子,假如有人要用Java实现一个单向链表类,可能会这样写...

weixin_39554775的博客 300

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

转自微信公众号【程序员江湖】 “首先,一个java bean 其实就是一个普通的java 类, 但我们对这个类有些要求: 1. 这个类需要是public 的, 然后需要有个无参数的构造函数 2. 这个类的属性应该是private 的, 通过setXXX()和getXXX()来访问 3. 这个类需要能支持“事件”, 例如addXXXXListener(XXXEvent e...

qq_40320556的博客 249

走进JavaWeb技术世界1:JavaWeb的由来和基础知识

本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下Star哈 文章首发于我的个人博客: www.how2playlife.com 本文是微信公众号【Java技术江湖】的《走进JavaWeb技术世界》其中一篇,本文部分内容来源于网络,为了把本文主题...

AliCoder的博客 663

JavaWeb—— 构建互联网世界的 “魔法砖石” 与实战密码

JavaWeb 是使用 Java 技术来解决相关 web 互联网领域的技术总和。它涵盖了服务器端编程、客户端编程、数据库交互等多个方面。Java 作为一种强大的面向对象编程语言,为 web 开发带来了高可靠性、高性能和丰富的类库支持。HTTP(Hypertext Transfer Protocol)是用于传输超文本的应用层协议。它是客户端浏览器和服务器之间通信的基础。HTTP 协议是无状态的,即服务器不会在两个请求之间保留任何信息。一个完整的 HTTP 交互包括请求和响应两个部分。

来自想要赚大钱的小周同学 1159

Java面试复习总结(JavaWeb篇9)——从JavaBean讲到Spring

目录 Java Bean JSP + Java Bean Enterprise Java bean Spring JavaBean 和 Spring中Bean的区别 Jave bean springbean 参考文章 Java Bean Java语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java ...

Slayer_Zhao的博客 168

JavaWeb前端与Spring MVC

1.背景介绍 JavaWeb前端与Spring MVC是一种常用的Web应用开发技术,它结合了JavaWeb和Spring MVC框架,使得开发者可以更加高效地构建Web应用。在本文中,我们将深入探讨JavaWeb前端与Spring MVC的核心概念、算法原理、具体操作步骤以及数学模型公式。同时,我们还将通过具体代码实例来详细解释这一技术的实现细节。 1.1 JavaWeb前端与Spring ...

AI天才研究院 1215

Javaweb研发的发展史以及演变过程

一、背景 首先介绍一个整理文章的背景:本来打算学习web容器是如何加载web应用程序的,越了解越深入,发现自己有很多地方都是模棱两可的,这时就对javaweb的前世今生产生了很大好奇,于是查询各种资料和对比,查阅大量资料的同时突然明白了一些问题,了解javaweb开发的前世今生对javaweb的开发有很大的帮助加深理解; Javaweb的早期发展:使用Javaweb技术实现时可以借助于多种相关的技术,如常见的JavaBean、servlet、等,也可以使用支持MVC的设计框架,常见的框架有 s...

liuyaguang0606的博客 3827

学习JavaWeb的总结

总的来说,学习JavaWeb是一次充满挑战而又有意义的经历。它让我对Web开发和企业级应用有了更全面和深入的理解,也培养了我的动手能力和解决问题的勇气。我相信,在不久的将来,JavaWeb会继续发展壮大,成为企业级应用开发的重要工具之一,而我也会继续深入学习和探索,不断提升自己的JavaWeb技能。愿我们共同进步,共同成长!

qq_73578372的博客 2223
上一篇: 走进JavaWeb技术世界9:Java日志系统的诞生与发展
下一篇: 走进JavaWeb技术世界14:Mybatis入门
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值