Spring IOC

Spring是一个轻量级框架(相较EJB,文件容量较小,需要的资源负担小)
Spring两个目标:

  1. 让现有技术更易于使用;
  2. 促进良好的编程习惯(称为最佳实践)。

Spring的两大核心:

  1. Spring IoC(控制反转)/依赖注入(Dependency Injection);
  2. AOP(Aspect Oriented Pogramming),即面向切面编程;

Spring贯穿表现层,业务层和持久层。提供“一站式”选择,然而Spring并不想取代已有的框架,而是以高度开放性与它们无缝整合。

Spring框架大约由20个功能模块组成。
20个功能模块分为6个部分:


Spring体系结构图
Core Conainer Data Access/Integration Web AOP Intrumentation Test
核心容器 数据访问/集成 web AOP(面向切面编程) 工具 消息和测试

控制反转(Inversion of Control ,IoC)

控制反转也称作依赖注入,是面向对象编程中的一种设计理念,用来降低代码之间的耦合度,同时也有利于代码的扩展。


这里有个工厂模式的例子:

/**
*创建一个Animal接口
*/
public interface Animal {
    public void eat();//定义接口的方法吃食物
    public void sport();;//定义接口的方法运动
}
/**
*创建一个Cat类实现Animal接口
*/
public class Cat implements Animal {
    @Override
    public void eat() {
        System.out.println("猫喜欢吃鱼!");
    }
    @Override
    public void sport() {
        System.out.println("猫很懒,不喜欢运动。");
    }
}
/**
*创建一个Dog类实现Animal接口
*/
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("狗喜欢吃肉!");
    }
    @Override
    public void sport() {
        System.out.println("狗在追飞盘。");
    }
}
/**
*创建Factory类
*/
public class Factory {
    private static final String CAT = "cat";
    private static final String DOG = "dog";
    public Animal getAnimal(String str) {
        if (CAT.equals(str)) {
            return new Cat();    
        }
        if (DOG.equals(str)) {
            return new Dog();
        }
            return null;
    }
}
/**
*创建测试类
*/
import org.junit.Test;

public class TestAnimal {
    @Test
    public void testFactory() {
        Factory factory = new Factory();
        Animal animal = factory.getAnimal("cat");
        animal.eat();
        animal.sport();
    }
}
运行结果:
猫喜欢吃鱼!
猫很懒,不喜欢运动。

从以上代码可以看出,实现类Cat和实现类Dog不再依靠自身的代码去获得所依赖的具体的Animal对象,而是把这一个工作交给第三方——Factory类,从而避免了和具体的Animal实现类之间的耦合。在如何获取所依赖的对象上,控制权发生了反转,从实现类Cat和实现类Dog转移到了Factory,这就是控制反转

Spring框架提供了完整的IoC实现,让程序员更专注于业务的编写。


依赖注入:
依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见的方式之一。
依赖注入的方式:
例子:

/**
*创建Person类
*/
package com.bean;
public class Person {

    private String name;
    private Integer age;

    public Person() { 
     }
    
    public Person(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }
  
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age =age;
    }

    public void showInfo() {
       System.out.print("一个叫"+name+"的人,今年"+age+"岁了。")
    }

}
  • 设值注入(必须要有setter方法)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="person" class="com.bean.Person">
      <property name="name" value="楠楠"/>
      <property name="age" value="5"/>
  </bean>
</beans>
  • 构造注入(必须设置构造器)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
   <bean class="com.bean.Person" id="person">
        <constructor-arg name="name" value="楠楠"></constructor-arg>
        <constructor-arg name="age" value="5"></constructor-arg>
   </bean>
</beans>
  • P命名空间注入(本质上也属于设值注入,也需setter方法)
<!-- 注意需在头文件中加入xmlns:p="http://www.springframework.org/schema/p" -->

<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-2.5.xsd">
    <bean id="person" class="com.bean.Person"
          p:name="楠楠" p:age="5"/>
</beans>

构造注入与设值注入的区别:

  • 设值注入方法支持大部分的依赖注入,如果我们仅需要注入int、String和long类型的变量,我们则不需要使用设值的方法注入,因为对于基本类型,我们可以为基本类型设置默认值。构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则会报错。
  • 设值注入不会重写构造方法的值,如果对于同一个变量同时使用构造方法注入又使用了设值方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。很明显,因为构造方法在对象被创建时调用;
  • 在使用设值注入时有可能还不能保证某种依赖是否已经被注入,这时对象的依赖关系有可能不完整,而在另一种情况下,构造注入则不允许生成依赖关系不完整的对象;
  • 在设值注入时如果对象A和对象B互相依赖,在创建对象A时Spring会抛出objectcurrentlyincreationexception异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然,所以Spring用设值注入的方法解决了循环依赖的问题,因为对象的设值方法是在对象被创建之前被调用的。

如何使用注解实现依赖注入
Spring在2.5版本后开始支持用注解的方式来配置依赖注入,可以使用注解的方式来代替XML方式的bean描述,这样将bean的描述转移到组件类的内部,只需在相关类上、方法上或者字段上使用注解即可,注解将会被容器在XML注入之前被处理之前被处理,所以后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的,所以需要在Spring文件中配置才能使用基于注解的装配模式

<beans>
    <context:annotation-config/>
<beans>

配置完<context:annotation-config/>就可以使用注解的方式在Spring中向属性,方法和构造方法中装配变量了。

几种重要的注解类型:

  1. @Required:该注解应用于设值方法;
  2. @Autowired:该注解应用于有值设值、非设值方法、构造方法和变量;
  3. @Qualifier:该注解和@Autowired注解搭配使用,用于消除特定bean自动装配的歧义;
  4. @JSR-250 Annotations:Spring支持基于JSR-250注解的以下注解:
  • @Resource
  • @PostConstruct
  • @PreDestroy

Spring的自动装配:
在Spring框架中,Spring容器还可以自动装配合作关系bean之间的关联关系。这意味着Spring可以通过向BeanFactory中注入的方式自动搞定bean之间的依赖关系。自动装配可以设置在每个bean上,也可以设定在特定的bean上。

  1. 在XML配置文件中表明如何根据名称将一个bean设置为自动装配
<bean bean id="person" class="com.bean.Person" autowired="byName">
  1. 使用@Autowired注解来完成自动装配指定的bean,使用之前需配置
<beans>
    <context:annotation-config/>
<beans>

或者在配置文件中配置

<bean class="org.springframework.beans.facyory.annotation.AutowriedAnnotationBeanPostProcessor"/>

配置完后即可使用@Autowired实现自动装配了。

自动装配模式:
Spring框架中5种自动装配:

  1. no:Spring框架的默认设置,在该设置下自动装配是关闭的,需自行在bean定义中用标签明确的设置依赖关系;
  2. byname:可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在配置文件中查询一个匹配的bean,如果找到的话,就装配曾属性,没找到就报错;
  3. byType:可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在配置文件中查询一个匹配的bean,如果找到的话,就装配曾属性,没找到就报错;
  4. constructor:构造器的自动装配和byType模式类似,但仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么会抛出异常;
  5. autodetect:该模式自动探测使用构造器自动装配或者byType自动装配,首先会尝试找合适的带参数的构造器,如果找到的话就是构造器自动装配,如果在bean内部没有找到相应的构造器或是无参构造器,容器就会自动选择byType的自动装配模式。
就到这里了啊!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,710评论 4 376
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,839评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,295评论 0 255
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,776评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,198评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,074评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,200评论 2 322
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,986评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,733评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,877评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,348评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,675评论 3 265
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,393评论 3 246
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,209评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,996评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,212评论 2 287
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 36,003评论 2 280

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,112评论 18 139
  • 来源:关于Spring IOC (DI-依赖注入)你需要知道的一切作者:zejian Dao层(AccountDa...
    杨井阅读 5,277评论 0 27
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan阅读 4,046评论 2 7
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,432评论 6 342
  • 昨天晚上8点多,孩子边听喜马拉雅里的连载故事《西游记》,边用毛笔在纸上胡乱涂鸦。她想画盘丝洞里的七个蜘蛛精...
    驼安阅读 156评论 0 0