zoukankan      html  css  js  c++  java
  • 浅谈spring框架的控制反转和依赖注入

    spring是什么?

    spring是一个轻量级的控制反转和面向切面编程的开源容器框架。

    轻量级是说spring框架本身的体积小。

    控制反转(Ioc):它不是技术,而是一种思想,将创建对象的控制权力交给spring框架。

    依赖注入(DI):指Spring创建对象的过程中,将对象依赖的属性(简单值,集合,对象)通过配置的方式进行设值。

    IoC和DI其实是同一个概念的不同角度描述,DI相对IoC而言,明确描述了被管理的对象中,依赖的属性也应该由Spring容器自动注入

    面向切面编程(AOP):零散存在于业务层中的功能代码(例如:日志,事务),称为横切面关注点。把一个个横切面关注点放到某个模块中,称为切面。

    AOP就是把多个方法前后的共同代码抽离出来,使用动态代理机制来控制。好处是降低耦合度,减少重复代码,提高代码的可扩展性和可维护性。

    Ioc容器

    spring的容器对象有BeanFactory和ApplicationContext。

    BeanFactory和ApplicationContext的区别:

    BeanFactory是spring的最顶层的接口,而ApplicationContext继承了BeanFactory,常用的实现类是ClassPathXmlApplicationContext。

    BeanFactory创建对象是在需要对象bean的时候才会创建,而ApplicationContext创建对象的时机是在加载容器时就会创建出所有的bean。

    使用xml方式创建对象:

    在spring配置文件中创建<bean></bean>标签,设置相应id和class属性。

    <?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="user" class="com.myspring.user.User">
        </bean>
    
    </beans>

    使用注解方式创建对象:

    Ioc创建对象的注解有四个:@component,@controller,@service,@repository

    它们的作用都是把被贴上注解的类交给spring管理,由spring自动的创建对象。

    区别是:@controller用于标注控制层组件,@service用于标注业务层组件,@repository用于标注数据访问组件,也就是DAO组件,当组件不好归类时使用@component。

     

    使用Ioc注解的前提:配置文件中要有Ioc注解解析器,在配置文件中加一行配置<context:component-scan base-package="com.spring.mybackage">,base-package告诉spring去哪些包里面扫描bean,如果有多个包需要被扫描,用逗号分开即可。如果是一些没有源码的类,比如框架内部定义好的类,就只能通过xml方式,不能用注解方式,因为我们改变不了那些源代码。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           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
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:property-placeholder location="classpath:db.properties"/>
    
        <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driverClassName}"></property>
            <property name="url" value="${jdbc.url}"></property>
            <property name="username" value="${jdbc.username}"></property>
            <property name="password" value="${jdbc.password}"></property>
        </bean>
    
        <context:component-scan base-package="com.myspring.login"/>
    
    </beans>

    IoC的注解方式可以认为是代替了原来在配置文件中配置的<bean id="user" class="com.myspring.user.User"></bean>标签。

    依赖注入DI

    在spring创建对象的过程中,需要将对象依赖的属性也自动的进行赋值,并且如果使用DI为A对象注入B对象,那么需要A和B都在spring容器中。

    setter注入方式(前提属性必须有set方法)

    在xml配置文件的<bean></bean>标签中手动配置一个<property></property>标签,<property>有两个属性。name属性的值就是对象中属性的名字。注入值需要先判断该属性的数据类型。

    如果是简单数据类型,使用value属性进行注入(setter注入方式本质是在执行set方法,如果对象的属性名字是abc,那么spring会自动找setAbc方法,跟对象中是否有这个字段无关。并且spring在注入值时隐含着类型转换,可以自动把string类型转换成Integer)。

    如果是引用数据类型,使用ref=""引用一个对象,引用数据类型ref的值是spring容器中已经存在的对象的id值。

    如果是集合数据类型,就要使用集合各自对应的标签进行注入。(注意:注入集合类型的数据时,集合的泛型会影响输出的结果)。

     <bean id="user" class="com.myspring.user.User">
            <property name="name" value="张三"></property>
            <property name="age" value="20"></property>
     </bean>

    构造器注入方式

    对象中必须存在有参构造,哪些属性需要注入值,构造函数就要有对象的参数,和setter方式类似,只需要将<property>标签替换为<constructor-arg>标签。<constructor-arg>标签中的name属性的值要和有参构造中的形参一致。

    <bean id="user" class="com.myspring.user.User">
            <constructor-arg name="name" value="jack"/>
            <constructor-arg name="age" value="18"/>
    </bean>

    使用注解的注入方式

    DI注解可以认为是代替了原来在配置文件中配置的<property name="name" value="张三"></property>标签。

    在spring中使用注解方式完成DI操作,一是使用spring自带的@Autowired,二是使用JavaEE规范提供的注解@Resource。二者功能相同。

    @Autowired可以让spring自动的把对象需要的属性从spring容器中找出来,并注入给该属性。@Autowired可以贴在字段或者set方法上,但一般贴在字段上,因为使用@Autowired没有set方法也可以注入,但是@Autowired的底层还是使用了setter方式注入。

    @Autowired和@Resource的区别

    @Autowired会先按照依赖对象的类型找,没有找到默认会报错,如果找到一个,直接注入;如果在spring容器中找到多个匹配的类型,再按照名字找,没有找到会报错。

    @Resource会先按照名字找,没有找到才会按照类型去找。

    为什么DI注解不需要注解解析器?

    spring容器在启动时会自动加入解析器,所以注解会生效。DI注解解析器是<context:annotation-config/>,但是在spring3.0之前,需要手动配置DI注解解析器。

  • 相关阅读:
    iOS开发-类簇(Class Cluster)
    算法-有向图及可达性
    算法-无向图(连通分量,是否有环和二分图)
    算法-无向图(深度优先搜索和广度优先搜索)
    算法-无向图
    算法-散列表
    Red-Gate.NET.Reflector.v8.0.1.308(内含注册机Keygen与注册图解)
    [转]c#快捷键
    Windows常用性能计数器总结
    [转]C#程序性能优化
  • 原文地址:https://www.cnblogs.com/w998/p/11624330.html
Copyright © 2011-2022 走看看