一、初识Spring

1.Spring中IOC与DI的概念

IOC的定义:控制反转,将对象的创建交给spring来完成,可以降低代码之间的耦合度,他的实现方式常见的有2种依赖注入(dependency injection)与依赖查找(dependency look)

DI:依赖注入,是IOC的一种实现方式

官网中关于依赖注入的说明:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-setter-injection

依赖注入的2种实现方式:

通过set方法注入

通过构造方法注入

目前官网中只说了有这2种方式

2.依赖注入的举例说明

set方式:

对象的依赖:

<bean id="exampleBean" class="examples.ExampleBean">

    <!-- setter injection using the nested ref element -->

    <property name="beanOne">

        <ref bean="anotherExampleBean"/>

    </property>

    <!-- setter injection using the neater ref attribute -->

    <property name="beanTwo" ref="yetAnotherBean"/>

    <property name="integerProperty" value="1"/>

</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>

<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

常量的依赖:

<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>

p-namespace形式的引用(与上述的常量引用等价):

<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"/>

集合的依赖(不常见):

<bean id="moreComplexObject" class="example.ComplexObject">

    <!-- results in a setAdminEmails(java.util.Properties) call -->

    <property name="adminEmails">

        <props>

            <prop key="administrator">administrator@example.org</prop>

            <prop key="support">support@example.org</prop>

            <prop key="development">development@example.org</prop>

        </props>

    </property>

    <!-- results in a setSomeList(java.util.List) call -->

    <property name="someList">

        <list>

            <value>a list element followed by a reference</value>

            <ref bean="myDataSource" />

        </list>

    </property>

    <!-- results in a setSomeMap(java.util.Map) call -->

    <property name="someMap">

        <map>

            <entry key="an entry" value="just some string"/>

            <entry key ="a ref" value-ref="myDataSource"/>

        </map>

    </property>

    <!-- results in a setSomeSet(java.util.Set) call -->

    <property name="someSet">

        <set>

            <value>just some string</value>

            <ref bean="myDataSource" />

        </set>

    </property>

</bean>

同理构造方式的依赖于set依赖大体相同

构造方法的对象依赖:

<beans>

    <bean id="beanOne" class="x.y.ThingOne">

        <constructor-arg ref="beanTwo"/>

        <constructor-arg ref="beanThree"/>

    </bean>

    <bean id="beanTwo" class="x.y.ThingTwo"/>

    <bean id="beanThree" class="x.y.ThingThree"/>

</beans>

构造方法的常量依赖:

<bean id="exampleBean" class="examples.ExampleBean">

    <constructor-arg type="int" value="7500000"/>

    <constructor-arg type="java.lang.String" value="42"/>

</bean>

构造方法可以提供根据构造方法的下标实现依赖:

<bean id="exampleBean" class="examples.ExampleBean">

    <constructor-arg index="0" value="7500000"/>

    <constructor-arg index="1" value="42"/>

</bean>

c-property实现构造方法的注入:

<bean id="beanTwo" class="x.y.ThingTwo"/>

<bean id="beanThree" class="x.y.ThingThree"/>

<!-- traditional declaration with optional argument names -->

<bean id="beanOne" class="x.y.ThingOne">

<constructor-arg name="thingTwo" ref="beanTwo"/>

<constructor-arg name="thingThree" ref="beanThree"/>

<constructor-arg name="email" value="something@somewhere.com"/>

</bean>

<!-- c-namespace declaration with argument names -->

<bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"

c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

总结:

set与构造方法的依赖注入主要包含常量的依赖、对象的依赖、以及p-property或c-property的依赖、以及构造方法的依赖还支持根据参数的下标注入

具体的可以参照spring官方文档

3.Spring的三种编程风格

schemal-based: 及xml格式

annotation-based:及annotation注解的方式

java-based:及通过Configuration的形式加载bean,此种方式相当于是xml形式的java代码表现


第一种XML格式编程风格:

xml中的描述如下:


编写启动类:


第二种方式:annotation编程方式

在xml中定义扫描的路劲

dao中添加注解:


Service中添加注解并添加自动注入


第三种方式:Configuration的使用

指定一个加载类:

可以发现Configuration既可以与Annotaion一起使用也可以与xml一起使用,也可以与2种同时使用



此时的启动类需要使用 AnnotationConfigApplicationContext 来加载Configuration的注解

4.Spring的自动装配

在xml文件中需要描述大量的依赖属性 property 是不是会很繁琐,而实际代码中已经明确说明了需要某个类型的类

Service中已经明确说明了需要IndexDao类型,而IndexDao类型的实现类已经在xml中定义了,很繁琐?


通过 default-autowire 可以自动装配 Service中的dao类型,此处按照类型自动装配,结果也是可以成功运行的。


如果bytype此时有2个相同类型的IndexDao肯定会报错,如下:


发现了2个类型,报错了,如此时 default-autowire="byName" 就不会报错了

xml中的自动装配 byName 是根据set方法后的属性名来匹配的,如下案列:

IndexService的字段名为 indexDao ,set方法后的名称为 indexDao1


运行,发现找不到indexDao


将xml中的indexDao改为indexDao1运行



上述的装配方式为全局的装配,也可以通过如下的方式给某个对象单独指定单独的装配方式
<bean id="service" class="com.test1.IndexService" autowire="byName">

Annotaion中的自动装配是如果是Resource是通过 字段名来匹配的,此处与xml的自动状态有区别



结果显示其是根据字段名称来匹配加载的

@Resource与@Autowired的区别

Autowired:默认按照类型匹配,如果有多个相同的类型则按照名称匹配

Resource:默认按照名称匹配,如果名称不存在按照类型匹配

Resource也可以按照类型以及名称来匹配查找



5.spring的常用作用域

singleton: 单列模式

prototype: 原型模式

如果一个单列模型的类中注入了一个prototype类型的类,那么注入的类prototype会失效也会变成单列


如上图所示IndexService为单列模式,IndexDao为prototype,IndexService注入了IndexDao,最终打印出来的IndexDao也为单列,失去了原型模式的意义

解决方式有2种:

第一种,实现ApplicationContextAware接口,引入ApplicationContext


第二种方式,通过Lookup主动的去寻找


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容