一、初识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主动的去寻找


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容