思维导图:

spring bean 依赖关系存在哪里_spring

 

一.引言

依赖注入(dependency injection) DI

    其实以上三种装配模式的本质都是一样的,只是表现方式不同而已,他们有共同的三个问题:

  1. 实体类是如何被声明以及被装配的
  2. spring容器如何发现这种声明
  3. 如何运行spring环境

    最后,这三种装配模式不是互相独立的,可以互相配合,所以会介绍如何综合使用这三种装配模式.

二.自动装配

    依照上一节所提出的的三个问题,便可以自然而然的说明如何使用spring的自动装配.

2.1如何声明以及装配一个实体类

    通过使用@Component注解可以声明这是一个可以被注入的实体类.在实体类中可以使用@Autowired注解将已被声明的实体类注入另一个实体类中.

    废话不多说,上代码,在自动装配中一个@Component就足够了

/**
 * 如何声明为一个实体类
 *
 * @author : zhouhao
 * @date : Created in 2019/2/25 20:42
 */
@Component
public class StudentCard {
    private String cardNo = "11111";

    public String getCardNo() {
        return cardNo;
    }

    public void setCardNo(String cardNo) {
        this.cardNo = cardNo;
    }
}

    装配其他的实体类则需要@Autowired注解,可以用在域变量,构造方法,普通方法之上.根据下面所示代码可以简单总结一下@Autowired是和类的声明相关联的即映射关系是类声明而不是域变量的引用名或者方法声明的方法名称或者形参名称.

/**
 * 如何装配其他的实体类
 *
 * @author : zhouhao
 * @date : Created in 2019/2/22 21:28
 */

@Component
public class Student {
    /**
     * 可以直接在变量上使用@Autowired,并不需要有setter方法.
     */
    @Autowired
    private Book book;
    /**
     * 构造方法需要的参数则可以在构造方法上使用@Autowired
     */
    private StudentCard card;
    /**
     * 也可以在普通方法上使用@Autowired,方法名称不具有作用
     */
    private Phone phone;
    

    @Autowired
    public Student(StudentCard card){
        this.card = card;
    }

    @Autowired
    public void setPhone(Phone phone) {
        this.phone = phone;
    }

    public void info(){
        System.out.println("cardNo:" + card.getCardNo());
        System.out.println("bookName:" + book.getName());
        System.out.println("phoneNo:" + phone.getMblNo());
    }
}

2.2 spring容器如何发现这种声明

/**
 * 如何发现可注入实体类
 * 
 * 1.首先得使用@Configuration声明这是一个配置类
 * 2.然后使用@ComponentScan声明需要注入的实体类的包的位置
 * 
 *
 * @author : zhouhao
 * @date : Created in 2019/2/22 21:31
 */
@Configuration
@ComponentScan("com.zhouhao.springstudy.action")
public class AutoConfig {
   
}

2.3如何运行spring环境

    由于是试验测试性质的学习,所以配合JUnit搭建spring的环境.指定配置类在其他两种装配模式中是一样的所以后文不在叙述.

/**
 * 使用JUnit搭建spring环境
 * 
 * 1.JUnit可以通过@RunWith创建spring环境,SpringJUnit4ClassRunner.class是专用于此的类
 * 2.@ContextConfiguration则指定了配置类
 *
 * @author : zhouhao
 * @date : Created in 2019/2/22 21:44
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AutoConfig.class)
public class SpringTest {
    @Autowired
    Student student;

    @Test
    public void printInfo(){
        student.info();
    }
}

二.Java装配

/**
 * Java装配
 * 
 * 实体类的注入声明,装配,以及配置类声明都在这个类中.
 * 同样的,@Bean和类声明关联和方法名称无关,尽管返回对象是new的,但是由于默认是单例,所以只有一个对象
 * 当然,这并不影响实体类中使用@Autowired,前提是必须在这个配置类中声明
 *
 * @author : zhouhao
 * @date : Created in 2019/2/27 6:39
 */
@Configuration
public class JavaConfig {
    @Bean
    public StudentCard getStudentCard(){
        return new StudentCard();
    }
    
    @Bean
    public Student getStudent(StudentCard card){
        return new Student(card);
    }
}

    Java装配同自动装配不同点在于,Java装配将实体类的注入声明放入了配置类中,而自动装配只需要使用@Copoment并在配置类声明路径.

三.XML装配

3.1如何如何声明以及装配一个实体类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       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:component-scan base-package="com.zhouhao.springstudy.action" />--><!--自动扫描,可以不用写bean了-->

  <bean id="mathBook" class="com.zhouhao.springstudy.action.MathBook"/>
  <bean id="studentCard" class="com.zhouhao.springstudy.action.StudentCard"/>
  <bean id="phone" class="com.zhouhao.springstudy.action.Phone"/>

  <bean id="student" class="com.zhouhao.springstudy.action.Student">
    <constructor-arg ref="studentCard"/>
  </bean>

</beans>

    3.2 spring容器如何发现这种声明

/**
 * XML装配
 *
 * 与自动装配差别不大,只是需要将路径声明变为xml文件申明
 *
 * @author : zhouhao
 * @date : Created in 2019/2/27 7:11
 */
@Configuration
@ImportResource("classpath:spring.xml")
public class XmlConfig {
}

    以上就是如何使用XML文件进行装配,当然,只是最简单的使用,我们还以在xml中使用c命名空间和p命名空间来更加方便的装配需要注入的类也可以注入List,Set等.我认为使用XML的最重要的原因就是使用了比人的源码所以不方便使用自动装配,否则使用自动装配才是最好的,这也是并没有详细研究XML装配的原因.

四.组合配置类

    spring的三种装配模式并不是互相独立,鸡犬不闻,而是可以互相配合使用的.

/**
 * 配置类的混合使用
 * 
 * 使用@Import可以直接引入配置类,实际上代替了使用以下两种注解
 * 1.使用@ImportResource引入XML配置文件
 * 2.可以使用@ComponentScan引入包路径
 *
 * @author : zhouhao
 * @date : Created in 2019/3/4 8:22
 */
@Configuration
@Import({AutoConfig.class,JavaConfig.class})
//@ImportResource("classpath:spring.xml")
//@ComponentScan("com.zhouhao.springstudy.action")
public class AllConfig {
}

注:本篇文章由《Spring实战》第二章:装配Bean 总结而来,由于本人非计算机专业出身,许多知识实在是理解不能,总结有相当多的遗漏,乃是我看不懂所致,更别说其中内容肯定有大量的理解错误,万望大家提出批评,我好改正。