跳至主要內容

Spring控制反转IOC

pptg大约 2 分钟

1. 介绍

控制反转(Inversion of Control,IOC) 是一种设计思想, 将原本在程序中手动创建对象的控制权交给了Spring来管理,这样做的优点如下:

  • 降低了对象之间的耦合性,非IOC的过程如果要使用接口类的实现类的话,必须new一个实现类,这样如果出现了新的实现类不方便调整
  • 便于对资源的管理,比如容器可以方便的实现单例模式

存储对象的容器即IoC容器,本质上就是一个大Map,他的实现方法是依赖注入(Dependency Injection,DI)

2. IoC的配置和依赖注入

2.1 IoC配置的三种方式

向Spring的IoC容器中配置Bean存在三种方式: 1. xml配置:配置xx.xml,声明命名空间、配置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">
    <!-- services -->
    <bean id="userService" class="com.pptg.springframework.service.UserServiceImpl">
        <property name="userService" ref="userService"/>
    </bean>
</beans>

2. Java配置:创建@Configuration配置类,创建方法、返回实例并添加@Bean

@Configuration
public class BeansConfig {

    @Bean("userService")
    public UserServiceImpl userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(userDao());
        return userService;
    }
}

3. 注解配置:Spring会自动扫描带有@Component,@Controller,@Service,@Repository这四个注解的类,然后帮我们创建并管理,前提是需要先配置Spring的注解扫描器

@Service
public class UserServiceImpl {
}

2.2 依赖注入的三种方式

从IoC容器中获取Bean也有三种方式: 1. setter方式:xml通过property注入,本质上是先调用空构造函数new XXXX()创建对象,再根据property的值调用setXXX()注入值,所以需要构造函数和set函数

<?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">
    <!-- services -->
    <bean id="userService" class="com.pptg.springframework.service.UserServiceImpl">
        <property name="userService" ref="userService"/>
    </bean>
</beans>

2. 构造器方式:xml通过constructor-arg注入,本质上是通过constructor-arg的值作为参数,调用构造函数new XXXX(xxx)创建对象

<?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">
    <!-- services -->
    <bean id="userService" class="com.pptg.springframework.service.UserServiceImpl">
        <constructor-arg name="userService" ref="userService"/>
    </bean>
</beans>

3. 注解注入@Autowired,包含三个属性

  • Constructor:通过构造方法注入
  • byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写
  • byType:查找所有的set方法,将符合参数类型的bean注入

3. @Autowired

Autowired注解内容如下:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, 
    ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
  boolean required() default true;
}

@Autowired可以用在成员变量、构造器、和方法上,在使用他们的时候会自动根据参数的类型去IOC中寻找Bean

除了@Autowired之外,还有@Resource和@Inject注解,但他们两个并不是Spring实现的:

  • @Resource:JSR250规范,默认根据属性名进行自动装配
  • @Inject:JSR330规范,默认根据类型进行自动装配