手记

SpringBootCore这一篇就够了(part-1

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

Scopeexplain
singletondefault
prototypeScopes a single bean definition to any number of object instances.
requestOnly valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocketScopes 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

ModeExplaination
noDefault) 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.
byNameAutowiring 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.
byTypeLets 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).
constructorAnalogous 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


0人推荐
随时随地看视频
慕课网APP