springboot框架关于bean装配
framework这东西就是定义一套规范,使用者遵循这套规范,将会等到很大好处:加快开发效率、提高代码可维护性...
所以,我们要使用好framework,务必要了解他的规则,和定义这套规则的目的。否则,用起来,总是处于东施效颦的状态
1 装配的目的
bean加载的解耦
配置参数的处理
2 实现方式
2.1 bean加载的解耦
加载的可选方式
类工厂:属于基本的设计模式,实现范畴,不能支撑框架
配置文件,xml等。spring 开始的做法
java的anotation。Annotation-based,spring 2.5.6. Java-based configuration, Spring 3.0
2.2 配置参数的处理
代码写死。太土,框架不考虑
配置文件。配置大量的xml文件。spring开始真的做法
配置文件+代码。到了springboot,就是一个applicaiton.yml加上java annotation就可以搞定了。
2.3 xml vs java annotation
二者最终的结果,是一摸一样的
xml,对于人的阅读很友好,语义表达很充分。但是配置起来比较烦人
java annotation,需要你花不少时间先去研究他的用法。研究明白后,用起来很简便。
3 详解
3.0 IoC Container
org.springframework.context.ApplicationContext 是IoC容器。负责bean的初始化,配置和组装(instantiating, configuring, and assembling)
容器怎么知道要负责哪些,具体的配置参数是什么呢: configuration metadata。(The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata)
The configuration metadata is represented in
XML
Java annotations. From Spring 2.5
Java-based configuration. From Spring 3.0
典型的XML based ApplicationContext
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param- value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
// create and configure beans ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); // retrieve configured instance PetStoreService service = context.getBean("petStore", PetStoreService.class); // use configured instance List<String> userList = service.getUsernameList();
----------------- | |--------------->| The Spring |<---------------------------- Configuration | Container | Your Business Objects(POJOS) Metadata |________________| | | produces ____________V____________ | | | Fully Configured System | | Ready for Use | |_________________________|
3.1 bean的定义
Class: instantiating beans
Name
Scope
Constructor arguments : Dependency Injection
Properties : Dependency Injection
Autowiring mode
Lzay initialization mode
Initialization method
Destruction method
Class的实例化
构造方法
<bean id="exampleBean" class="examples.ExampleBean"/>
静态工厂方法
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/></bean>
public class ClientService { private static ClientService clientService = new ClientService(); private ClientService() {} public static ClientService createInstance() { return clientService; } }
实例的工厂类
<bean id="serviceLocator" class="examples.DefaultServiceLocator"> <!-- inject any dependencies required by this locator bean --></bean> <bean id="clientService" factory-bean="serviceLocator" factory-method="createClientServiceInstance"/> <bean id="accountService" factory-bean="serviceLocator" factory-method="createAccountServiceInstance"/>...
public class DefaultServiceLocator { private static ClientService clientService = new ClientServiceImpl(); private static AccountService accountService = new AccountServiceImpl(); public ClientService createClientServiceInstance() { return clientService; } public AccountService createAccountServiceInstance() { return accountService; } }
DI
Constructor-based Dependency Injection
reference<beans> <bean id="thingOne" class="x.y.ThingOne"> <constructor-arg ref="thingTwo"/> <constructor-arg ref="thingThree"/> </bean> <bean id="thingTwo" class="x.y.ThingTwo"/> <bean id="thingThree" class="x.y.ThingThree"/></beans>
by parameter type---------------------- <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg type="int" value="7500000"/> <constructor-arg type="java.lang.String" value="42"/> </bean by parameter index ---------------- <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg index="0" value="7500000"/> <constructor-arg index="1" value="42"/> </bean> by parameter name ---------------- <bean id="exampleBean" class="examples.ExampleBean"> <constructor-arg name="years" value="7500000"/> <constructor-arg name="ultimateAnswer" value="42"/> </bean> use p, c namespace ----------------- <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="thingOne" class="x.y.ThingTwo"/> <bean id="thingTwo" class="x.y.ThingThree"/> <!-- traditional declaration --> <bean id="thingOne" class="x.y.ThingOne"> <constructor-arg ref="thingTwo"/> <constructor-arg ref="thingThree"/> <constructor-arg value="something@somewhere.com"/> </bean> <!-- c-namespace declaration --> <bean id="thingOne" class="x.y.ThingOne" c:thingTwo-ref="thingTwo" c:thingThree-ref="thingThree" c:email="something@somewhere.com"/> </beans>
Setter-based Dependency Injection
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy- method="close"> <!-- results in a setDriverClassName(String) call --> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb"/> <property name="username" value="root"/> <property name="password" value="masterkaoli"/></bean>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/mydb" p:username="root" p:password="masterkaoli"/></beans>
Bean Scopes
Scope | explain |
---|---|
singleton | default |
prototype | Scopes a single bean definition to any number of object instances. |
request | Only valid in the context of a web-aware Spring ApplicationContext. |
session | Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext. |
application | Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext. |
websocket | Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext. |
==when a singleton bean has a prototype bean property!!!==
Autowiring Mode
Mode | Explaination |
---|---|
no | Default) No autowiring. Bean references must be defined by ref elements. Changing the default setting is not recommended for larger deployments, because specifying collaborators explicitly gives greater control and clarity. To some extent, it documents the structure of a system. |
byName | Autowiring by property name. Spring looks for a bean with the same name as the property that needs to be autowired. For example, if a bean definition is set to autowire by name and it contains a master property (that is, it has a setMaster(..) method), Spring looks for a bean definition named master and uses it to set the property. |
byType | Lets a property be autowired if exactly one bean of the property type exists in the container. If more than one exists, a fatal exception is thrown, which indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens (the property is not set). |
constructor | Analogous to byType but applies to constructor arguments. If there is not exactly one bean of the constructor argument type in the container, a fatal error is raised. |
3.2 annotation-based container configuration
@Componet + @ComponentScan + @Configuration
@Configuration @ComponentScan(basePackages = "org.example", includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"), excludeFilters = @Filter(Repository.class)) public class AppConfig { }
等价与
<beans> <context:component-scan base-package="org.example"> <context:include-filter type="regex" expression=".*Stub.*Repository"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan></beans>
作者:小乖猴
链接:https://www.jianshu.com/p/0f4d6fa1b365