Spring(二)spring核心技术——ioc

一、Spring核心技术——IOC

  IOC是Inversion of Control的缩写,即控制反转;是一种思想、理论、概念。IOC把对象的创建、管理、属性的赋值,都交给代码之外的容器实现,通过外部资源完成。使用ICO的目的就是在减少对代码改动的情况下,实现不同的功能,实现解耦合。

  • 控制:创建对象,对象的属性赋值,对象之间的关系管理。

  • 反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。由容器代替开发人员管理对象。创建对象,给属性赋值。

  • 正转:由开发人员在代码中,使用new构造方法创建对象,开发人员主动管理对象。

  • DI(Dependence Injection):依赖注入,是IOC的的技术实现,只需要在程序中提供要使用的对象名称就可以;至于对象如何在容器中创建,赋值,查找都由容器内部实现,其底层原理是反射机制。

二、使用IOC创建对象

1. Java中创建对象的方式

  • 构造方法(new)
  • 反射
  • 序列化
  • 克隆
  • 动态代理
  • IOC(容器创建对象)

2. 使用xml配置文件创建对象

  • 在spring主配置文件中使用<bean>标签为属性赋值。

  • 使用IOC可以创建自定义类的对象,也可以创建非自定义类的对象。

  • 同一个类可以使用多个<bean>标签创建不同名称的对象。


<?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为创建的对象的名称,因此值唯一 -->
    <bean id="object1" class="类的全名"></bean>

    <bean id="object2" class="类的全名"></bean>

    <!--spring可以创建已存在的非自定义的类,例如创建Java中的日期类对象-->
    <bean id="mydate" class="java.util.Date"></bean>

</beans>

3. 使用注解创建对象

  • @Component():可以对任意类创建对象

    语法:@Component(value="对象名称")  或   @Component("对象名称")   或   @Component()
    
    使用方法:首先在spring主配置文件中加入组件扫描器(component-scan),之后直接在类名上方加入该注解即可。
    
    @Component("myStudent")
    public class Student {
         }
    
    //未指定对象名称时,spring默认以类名首字母小写作为对象名
    @Component()
    public class Student {
         }
    
  • @Repository():用在持久层类的上面,创建dao层的对象。

  • @Service():用在业务层上面,创建service层的对象。

  • @Controller():用在控制层上面,创建控制层的对象。

  类和注解编写完成后需要在spring主配置文件中加入组件扫描器:

<context:component-scan base-package="类文件所在的包名" />

三、使用IOC为属性赋值

  Spring规定Java中的基本类型和String类型的数据均为简单类型,其他的均为引用类型。

1. 使用xml配置文件为属性赋值

  • set注入

  前提:set注入,顾名思义是使用类中的setXXX()方法进行属性的赋值,赋值时Spring会自动调用对应类中的对应setXXX()方法,因此如果使用set注入方式为属性赋值,类中就必须有相应的setXXX()方法。

  该方式是在<bean>标签中使用<property>标签,name的值为变量名称,value和ref为所要赋的目标值。

<bean id="对象名" class="类全名">
    <!--简单类型:使用属性value-->
    <property name="name" value="krain"/>
    <property name="age" value="23"/>
    <!--引用类型:使用属性ref-->
    <property name="school" ref="myschool"/>
</bean>
  • 含参构造注入

  前提:使用对应类的含参构造方法为属性赋值。Spring在创建对象时调用含参构造方法同时为属性赋值,因此舒勇此方法是必须设置含参构造方法。

使用含参构造注入为属性赋值有以下几种方式:

1)使用标签的name属性

<!--使用name属性-->
<bean id="student" class="cn.krain.ba03.Student">
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="age" value="12"/>
    <constructor-arg name="school" ref="myschool"/>
</bean>

2)使用标签的index属性

  <constructor-arg>标签中index属性的值为构造方法参数的顺序,从0开始。

<!--使用name属性-->
<bean id="student2" class="cn.krain.ba03.Student">
    <constructor-arg index="0" value="李斯"/>
    <constructor-arg index="1" value="21"/>
    <constructor-arg index="2" ref="myschool"/>
</bean>

3)省略index属性

  直接按构造方法的参数顺序赋值。

<!--使用name属性-->
<bean id="student3" class="cn.krain.ba03.Student">
    <constructor-arg value="王五"/>
    <constructor-arg value="34"/>
    <constructor-arg ref="myschool"/>
</bean>
  • 自动注入

  Spring可以根据byName或byType规则自动给引用类型赋值。

1)byName(按姓名注入)

要求:java类中引用类型变量的名称和bean标签id的名称一样,且数据类型是一致的

语法:`<bean name="xxx" class="yyy" autowire="byName"></bean>`

2)byType(按类型注入)

java引用数据类型和spring容器中(配置文件)`<bean>`中的class的值是同源(同一类)关系

以下三种情况可用byType:

    1)java类中引用类型的数据类型和bean的class的值是一类
    2)java类中引用类型的数据类型和bean的class的值是父子类关系
    3)java类中引用类型的数据类型和bean的class的值是接口与实现类的关系

注意事项:使用byType时,在xml配置文件中声明的bean只能有一个符合条件的,否则会报错

2. 使用注解为属性赋值

  • @Value()

  为简单赋值属性,直接在类中对应属性上方加入注解即可。

@Component("myStudent")
public class Student {
   
    @Value("张飞")
    private String name;
    @Value("233")
    private Integer age;
}
  • @Autowired()

  为引用类型属性赋值,有byName和byType两种方式,默认使用byType方式。

@Component("myStudent")
public class Student {
   

    @Value("张飞")
    private String name;
    @Value("233")
    private Integer age;
    /* * 为引用数据类型赋值:自动注入 byType byName * @Autowired:默认使用的是byType自动注入 * * 使用byName时: * 1.在属性上面加入@Autowired * 2.在属性上面加入@Qualifier("属性名,即bean的id") * */
    //使用byName
    @Autowired
    @Qualifier("mySchool")  //引用类型数据的名称
    private School school;

    //使用byType,根据属性的类型自动赋值
    @Autowired
    private School school;
}
  • @Resource()

  JDK中的注解,使用自动注入为引用类型属性赋值,支持byName、byType,默认是byName。

@Component("myStudent")
public class Student {
   

    @Value("张飞")
    private String name;
    @Value("244")
    private Integer age;

    /* * 使用@Resource:该注解来自jdk,spring框架提供了对这个注解的功能支持 * 同样是自动注入原理,支持byName byType,默认是byName * Resource会先使用byName注入,如果byName赋值失败,会自动使用byType */

    //默认为byName
    @Resource(name = "mySchool")
    private School school;

    //byType
    @Resource()
    private School school;

    ...
}

  类和注解编写完成后需要在spring主配置文件中加入组件扫描器:

<context:component-scan base-package="类文件所在的包名" />
全部评论

相关推荐

头像
11-09 12:17
清华大学 C++
out11Man:小丑罢了,不用理会
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务