spring的主要内容之依赖注入

---------------------------------------------------依赖注入的含义------------------

在上一篇中提到过,spring的主要目的是简化开发和松散耦合。依赖注入技术就是为了松散耦合而出现的。

在旧的编程观念中,A类如果需要B类的实例,就需要通过new关键字新建一个B类的实例。这种编程方式需要依赖类确定被依赖类的具体实现类。

如果使用spring的依赖注入技术,则依赖类只需要声明自己需要某个类的实例,而不需要确定被依赖类的具体实现类,具体的实现类由spring框架通过配置文件来确定。

使用spring的依赖注入技术可以松散耦合。当需要更换被依赖类的具体实现类时,只需要创建一个新的实现类,然后把spring配置文件中之前配置的实现类改为新的实现类即可,而不需要对依赖类做改动。

由此也可以看出,spring的依赖注入(DI)实际上是把被依赖类的具体实现类的确定权交给了spring框架,而不再是由依赖类来确定。因此,依赖注入也被称为控制反转。

---------------------------------------------------依赖注入发生的时机------------------

那么依赖注入发生在什么时候呢?是发生在项目启动的过程中的。

当我们启动项目时,spring会进行容器的初始化,spring会扫描整个项目,如果发现spring的xml配置文件、spring的注入注解、基于java的配置注解,就会实例化相关的类,这些类包括controller、service、dao等。这个过程中包含依赖注入。实例化得到的Bean将由spring容器管理。

我以前一直以为当页面发生事件请求controller时,spring才去实例化对应的controller类。现在看来,我之前的想法是错误的。controller类早在项目启动的过程中,就已经实例化了。当事件请求controller时,spring容器会在容器中找到对应controller的一个实例,然后执行对应的方法。

 

---------------------------------------------------依赖注入的步骤和方式------------------

总的看来,依赖注入的实现实际上分为三个步骤。第一是解析spring配置文件中配置的bean和java代码中的注解的bean。第二是实例化配置的所有bean。第三是注入依赖的bean。

注入方式共有三种,包括注解扫描注入、java配置注入、XML注入。

---------------------------------------------------分界线------------------

第一,注解扫描注入。

在java代码中注解bean,会用到spring的三个注解,分别是@ComponetScan、@Component和@Autowired。

@ComponentScan表示被注解的类所在包及其子包会被列入扫描范围。如果想把这个配置类和应用代码分开,则可以在一个单独的包中建立这个配置类,在这个类上使用@ComponentScan(basePackages="packageName")或者@ComponentScan(basePackages={"packageName1", "packageName2"})来指定扫描范围。为了代码的友好性,也可以使用@ComponentScan(basePackageClasses={A.class, B.class}),其含义为将这些类所在包及其子包列入扫描范围。

--->>>如果是使用配置文件来开启组件扫描,可以使用:<context:componet-scan base-package=""/>来指定。有人可能要问,既然可以使用注解配置,为什么还需要配置文件呢?因为如果依赖的是第三方工具类,我们是无法在第三方工具类上加@Component注解的,所以只能通过配置文件添加依赖了,配置文件只需指定第三方工具类的路径即可。

@Component是用来注解类的,用@Component注解一个类,就告诉了spring要在容器中创建这个类的实例并管理它,此时创建的实例的id为小写首字母的类名。如果要指定特定的实例名称,可以使用@Component("beanName")。

其实,@Component是通用的注解,一般我们为了提高可读性,会使用@Controller、@Service、@Repository等具体的注解。在项目启动过程中,spring容器会进行初始化。初始化时如果发现@Controller注解,就会实例化这个controller类。其他注解也是如此。

@Autowired是用来注解属性、构造方法、set方法、或一般带参方法的,告诉spring为这个属性或方法注入一个符合要求的实例。

---------------------------------------------------分界线------------------

第二,java配置注入。

 

package com.zaoren.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zaoren.controller.UserController;
import com.zaoren.service.UserService;

@Configuration
public class BeanConfiguration {
    
    @Bean(name="uService")
    public UserService userService() {
        System.out.println("create userService");
        return new UserService();
    }
    
    @Bean
    public UserController userController(UserService uService) {
        System.out.println("create userController");
        UserController uController = new UserController(uService);
        
        return uController;
    }
}

----------------------------------------------------------------------
import org.springframework.web.bind.annotation.RequestMethod;

import com.zaoren.service.UserService;


@RequestMapping(value="user")
public class UserController {
    
    private UserService uService;

    @RequestMapping(value="buy",method=RequestMethod.GET)
    public void buy() {
        System.out.println("--------->>>buy a book.");
        uService.searchBook();
    }
    
    public UserController(UserService uService){
        this.uService = uService;
    }
}

 

 spring初始化容器时会扫描项目文件,当发现类被@Configuration注解时,就知道这个类是用来装配实例的,然后才会扫描具体的方法并创建实例。如果没有@Configuration注解,则@Bean注解将不会起作用,即不会执行此文件中创建实例的方法。

@Bean注解告诉了spring框架,这个方法要返回一个bean,要求spring框架按照这个方法的逻辑创建实例,并纳入spring上下文中进行管理。

其实@Configuration有些类似于xml配置方式中的<beans>标签,@Bean类似于xml配置方式中的<bean>标签。

通过@Bean创建的实例的id默认是方法名(此处即aClass)。如果想要自定义实例id,可以这样指定id:@Bean(name=“myBean”)。

 

转载于:https://www.cnblogs.com/jxdr/p/11424010.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值