摘要:每个属性参数构造函数中值的类型都能够被成字符串类型。对比上文给出的个代码片段,可发现皆在用不同的方法进行元数据配置,并且被配置的具体对象是数据库驱动。
@(SPRING FRAMEWORK)
〔4〕7.4 Dependencies声明:
斜体字:《官档》原文
斜体加粗字:《官档》原文的重点字、词、句
正体字+前置〔〕:个人表述行为,如:〔总结〕、〔分析〕等
灰体字:生词
粉体字:疑问
[TOC]
A typical enterprise application does not consist of a single object
〔总结〕一个典型的程序,是需要多个对象相互协作
how you go from defining a number of bean definitions that stand alone to a fully realized application where objects collaborate to achieve a goal.
〔总结〕定义一群具备相互协作能力的对象,以实现目标程序
Dependency injection (DI):is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies on its own by using direct construction of classes, or the Service Locator pattern.
1.1 Constructor-based dependency injection关键词:
Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency.
Calling a static factory method with specific arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a constructor and to a static factory method similarly.
示例代码
public class SimpleMovieLister { // the SimpleMovieLister has a dependency on a MovieFinder private MovieFinder movieFinder; // a constructor so that the Spring container can inject a MovieFinder public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // business logic that actually uses the injected MovieFinder is omitted... }
〔总结〕基于构造函数的依赖注入,其核心在构造函数上,即重点需要放在一个疑问点上:构造函数如何影响依赖注入(依赖注入的成功标准:一个bean对象已完成实例化)?
一个规范:顺序
示例代码
package x.y; public class Foo { public Foo(Bar bar, Baz baz) { // ... } }
第1种bean引用方式:引用引用类型
〔注意〕bean引用方式是指:容器在实例化化一个bean时,需要读取配置元数据。因为配置元数据中包含了可实例化一个POJO对象的所有必要数据
第2种bean引用方式:引用基本数据类型
package examples; public class ExampleBean { // Number of years to calculate the Ultimate Answer private int years; // The Answer to Life, the Universe, and Everything private String ultimateAnswer; public ExampleBean(int years, String ultimateAnswer) { this.years = years; this.ultimateAnswer = ultimateAnswer; } }
基于type属性
基于name属性
基于index属性
1.2 Setter-based dependency injection
关键词: no-argument
〔总结〕符合以下任一点,可选择基于setter的依赖注入
无参构造函数
无参工厂方法
public class SimpleMovieLister { // the SimpleMovieLister has a dependency on the MovieFinder private MovieFinder movieFinder; // a setter method so that the Spring container can inject a MovieFinder public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // business logic that actually uses the injected MovieFinder is omitted... }
〔总结〕对比基于带参构造函数依赖注入和基于setter依赖注入,可以发现:基于构造函数的不需要提供setter/getter,基于setter的不需要提供带参构造函数
Q: Constructor-based or setter-based DI?
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property a required dependency.
可以混搭一起用。根据实际开发经验,以Constructor-based DI为主,以setter-based DI为辅。主是强制,辅是可选。
The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.
Constructor-based DI能确保
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.
Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.
〔总结〕懵逼¬_¬
1.3 Dependency resolution process〔总结〕执行注入的步骤(详见《官档》):
ApplicationContext根据配置元数据装配所有bean对象
当依赖的具体表现形式为以下时:
properties
constructor arguments
arguments to the static-factory method
那么ApplicationContext会根据配置元数据的信息为POJO对象引用到对应的bean对象上。
要保证在每个属性,参数构造函数能设值的时候,必须提供值,这个值:可以是基本值,也可以是引用值。
每个属性、参数构造函数中值的类型都能够被Spring convert成字符串类型。
如何解决Circular dependencies ?
Circular dependencies场景:
Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection.
If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.
Circular dependencies异常解决方案:
you can configure circular dependencies with setter injection.
代码案例:参见《官档》
2. Dependencies and configuration in detail 2.1 Straight values观察以下三个代码片段:
代码片段 1 使用最原始的方式
代码片段 2 : 使用p-namespace配置元数据
代码片段 3:使用java.util.Properties
jdbc.driver.className=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mydb
〔总结〕
1. 阅读对应《官档》后,依旧对小标题#Straight values#的具体含义模糊不清,不清楚其牵引下文的意图是什么。
2. 对比上文给出的3个代码片段,可发现:皆在用不同的方法进行元数据配置,并且被配置的具体对象是数据库驱动。
关键词:ref
The ref element is the final element inside a ①
〔总结〕从上文可得
ref属性在哪用,有什么用
略提bean作用域、bean验证对bean对象的影响。
示例代码
2.3 Inner beansclass="org.springframework.aop.framework.ProxyFactoryBean">
〔总结〕inner bean类似于Java的内部类
2.4 CollectionsCollection merging
Limitations of collection merging
Strongly-typed collection
Spring Collections | 映射 | Java Collections |
---|---|---|
—— | List | |
—— | Set | |
—— | Map | |
—— | Properties |
示例代码
administrator@example.org support@example.org development@example.org just some string
〔总结〕根据示例代码,得以下结论:
的key、value;
bean | ref | idref | list | set | map | props | value | null2.5 Null and empty string values
示例代码:2种方式为字符串设置NULL或空值
设空值时, 第1种方式:
设空值时, 第2种方式:
exampleBean.setEmail("")
设NULL时, 第1种方式:
设NULL时, 第2种方式:
exampleBean.setEmail(null)2.6 XML shortcut with the p-namespace
代码片段
代码片段 :使用p:spouse-ref=""
2.7 XML shortcut with the c-namespace
代码片段
2.8 Compound property names
代码片段:确保fred,bob属性的值不为空,即确保不抛 NullPointerException异常
3. Using depends-on
depends-on的作用:
explicitly force one or more beans to be initialized before the bean using this element is initialized.
使用depends-on的场景:
a static initializer in a class needs to be triggered.
database driver registration
代码片段 1
代码片段 2
〔总结〕参阅现有博客提供的博主,及具体应用场景
4. Lazy-initialized beans延迟加载(初始化)bean对象。
By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.
代码示例
When the preceding configuration is consumed by an ApplicationContext, the bean named lazy is not eagerly pre-instantiated when the ApplicationContext is starting up, whereas the not.lazy bean is eagerly pre-instantiated.
However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean elsewhere that is not lazy-initialized.
代码示例: 控制懒加载级别
〔总结〕参阅《官档》,多次阅读原文旨意。
5. Autowiring collaborators自动装配的优势?
自动装配的劣势?
自动装配的模式?
自动装配的限制?
自动装配的应用?
〔总结〕Spring有能力自动装配协作者(即对象之间存在依赖关系)。
自动装配的优点:
Autowiring can significantly reduce the need to specify properties or constructor arguments.
Autowiring can update a configuration as your objects evolve. For example, if you need to add a dependency to a class, that dependency can be satisfied automatically without you needing to modify the configuration.
〔理论总结〕使用自动装配后,配置文件具备自更新能力。主流开发的趋势之一。
autowire //基于XML5.1 Limitations and disadvantages of autowiring
Explicit dependencies in property and constructor-arg settings always override autowiring. You cannot autowire so-called simple properties such as primitives, Strings, and Classes (and arrays of such simple properties). This limitation is by-design.
Autowiring is less exact than explicit wiring. Although, as noted in the above table, Spring is careful to avoid guessing in case of ambiguity that might have unexpected results, the relationships between your Spring-managed objects are no longer documented explicitly.
Wiring information may not be available to tools that may generate documentation from a Spring container.
Multiple bean definitions within the container may match the type specified by the setter method or constructor argument to be autowired. For arrays, collections, or Maps, this is not necessarily a problem. However for dependencies that expect a single value, this ambiguity is not arbitrarily resolved. If no unique bean definition is available, an exception is thrown.
5.2 Excluding a bean from autowiring禁用某特定bean的自动装配功能
用法
作用
5.2.1 用法基于XML
autowire-candidate=false
基于注解
@Autowired5.2.2 作用
unavailable to the autowiring infrastructure.
only affect type-based autowiring.
主要用于解决以下场景:
在大多数应用场景中,bean对象一般都是单例对象。但在bean对象的依赖情况下:
一个单例依赖另一个单例
一个非单例依赖另一个非单例
古老的做法:是将一个bean定义为另一个bean的属性。以此建立依赖关系。
如:A-bean 依赖 B-bean,那么POJO可定义为:
public class A{ public B b; } public class B{}
bean之间的依赖关系建立后,会产生一个问题: 两个bean的生命周期不一样,怎么办?
古老的做法是这样子的,见代码示例:
【代码示例说明】:
CommandManager obejct在系统架构中属于业务逻辑层(SERVICE)。
CommadManger object的开放式方法process(Map commandState)的调用依赖Command obejct。
根据【1.】和【2.】可得,两个类之间存在密切的依赖关系。所以Spring提供一种方式:当依赖方(CommandManager)的行为受制于被依赖方(Command)时,可以在依赖方内部实现被依赖方的初始化。完成上述行为的前提的是:依赖方(CommandManager)需要实现接口ApplicationContextAware。
// a class that uses a stateful Command-style class to perform some processing package fiona.apple; // Spring-API imports import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; //依赖方(CommanderManager)现了ApplicationContextAware public class CommandManager implements ApplicationContextAware { private ApplicationContext applicationContext; //process()的执行受制于Command对象 public Object process(Map commandState) { Command command = createCommand(); command.setState(commandState); return command.execute(); } protected Command createCommand() { // notice the Spring API dependency! return this.applicationContext.getBean("command", Command.class); } public void setApplicationContext( ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
这种做法需要你放弃Spring framework的IoC特性。以上述代码来看,bean object有两个:CommandManager和Command。需要分析以下几个问题
两个bean object中,依赖方是谁? 被依赖方又是谁?
answer:依赖方:CommandManager; 被依赖方:Command。
被依赖方的bean obejct的生命周期如何得到保证?
answer:要保证被依赖方的生命周期随时不死。那么依赖方实现接口ApplicationContextAware,目的是为了调用Spring framework的方法
这种在业务层耦合Spring framework代码已破化IoC原则,因为在实现接口的那一刻起,IoC原则就已经被破坏了。即这种解决方案不可取。Spring给出了2种可靠的方案:
lookup method injection
arbitrary method replacement
〔经验之道〕业务层的所有代码应该满足以下注释要求
// no more Spring imports!6.1 Lookup method injection
参阅《官档》,思考代码示例逻辑
6.2 Arbitrary method replacement参阅《官档》,思考代码示例逻辑
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/70372.html
摘要:本部分是可以找到有关功能和概念的大部分信息的地方。促销系统包含一个高度可配置的促销系统。异步消息通过与现代代理交互,实现应用程序消息的异步处理。将智能地将自己的配置信息与实施者在运行时提供的信息合并。添加了方法以允许包含任何符合的加密方案。 本部分是可以找到有关Broadleaf功能和概念的大部分信息的地方。我们描述了购物车修改,定价和付款等操作的重要性,以及Broadleaf支持的其...
摘要:节前没有新业务代码,正好刚发布,于是开始为期四天的框架代码升级。还好并没有使用它的,配置上有一个小坑,的是表示而是表示,之前配置成的,如果到的里面那就要抛异常了。 节前没有新业务代码,正好Greenwich刚发布,于是开始为期四天的框架代码升级。 之前的版本是 spring boot 1.5.10 , spring cloud Edgware.SR3 依赖升级 增加依赖管理插件 ap...
此文章为Spring Boot Reference Guide(2.1.5.RELEASE)的备忘录。 Chapter 8. Introducing Spring Boot You can use Spring Boot to create a Java application that can be started by using java -jar or more traditional w...
摘要:栈长有话说其实项目就是为了阿里的项目能很好的结合融入使用,这个项目目前由阿里维护。对同时使用和阿里巴巴项目的人来说无疑带来了巨大的便利,一方面能结合无缝接入,另一方面还能使用阿里巴巴的组件,也带来了更多的可选择性。 最近,Spring Cloud 发布了 Spring Cloud Alibaba 首个预览版本:Spring Cloud for Alibaba 0.2.0. 大家都好奇,...
阅读 2513·2021-11-24 10:20
阅读 2348·2021-09-10 10:51
阅读 3340·2021-09-06 15:02
阅读 3066·2019-08-30 15:55
阅读 2809·2019-08-29 18:34
阅读 3025·2019-08-29 12:14
阅读 1169·2019-08-26 13:53
阅读 2865·2019-08-26 13:43