Spring注解版--Spring自动装配

Spring注解版–Spring自动装配:

最近在看spring注解的网上视频教程,为了以后回头看看,我将内容写了下来,如下:

1.环境配置

1.1、创建一个Maven工厂

​ 我们在idea中创建一个maven的quickstart工程。

​ 我们在pom.xml依赖中添加需要添加的依赖。

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.2.RELEASE</version>
    </dependency>
  </dependencies>

1.2、创建相关的类

  • 创建dao数据访问层

我们在目录下创建dao包,在此包下面创建一个MyDao的类文件,此文件的类名上面添加了注解@Repository

MyDao:

package com.xiaojian.dao;

import org.springframework.stereotype.Repository;

@Repository
public class MyDao {

}
  • 创建service服务层

我们在目录下创建service包,在此包下面创建MyService的类文件,此文件的类名上面添加了注解@Service

MyService:

package com.xiaojian.service;

import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Autowired
    private MyDao myDao;
    

    @Override
    public String toString() {
        return "MyService{" +
                "myDao=" + myDao +
                '}';
    }
}
  • 创建controller控制器

我们在目录下创建controller包,在此包下面创建一个MyController的类文件,此文件的类名上面添加了注解@Controller

MyController:

扫描二维码关注公众号,回复: 5351051 查看本文章
package com.xiaojian.controller;

import com.xiaojian.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class MyController {

    @Autowired
    private MyService myService;

    @Override
    public String toString() {
        return "MyController{" +
                "myService=" + myService +
                '}';
    }
}

2.自动装配:

​ Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系的赋值。

2.1、@Autowired自动注入(spring注解)

2.1.1、@Autowired注入实例

2.1.1.1、创建配置类

我们在目录下创建config包,在此包下面创建MainConfigOfAutowired类文件,此类作为配置类。

MainConfigOfAutowired:

package com.xiaojian.config;

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

@Configuration  //此类作为配置类
//扫描service、dao、controller三个包下面的配置类。
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {
}

2.1.1.2、创建测试类

我们在目录下创建test包,在此包下面创建Test_MainConfigOfAutowired类文件。

Test_MainConfigOfAutowired:

package com.xiaojian.test;

import com.xiaojian.config.MainConfigOfAutowired;
import com.xiaojian.dao.MyDao;
import com.xiaojian.service.MyService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test_MainConfigOfAutowired {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

        //看看myservice这个对象里面注入的mydao的信息
        MyService myService = applicationContext.getBean(MyService.class);
        System.out.println(myService);

        //看看mydao这个对象的信息
        MyDao myDao = applicationContext.getBean(MyDao.class);
        System.out.println(myDao);

        applicationContext.close();
        
    }
}

2.1.1.3、测试运行

运行Test_MainConfigOfAutowired测试类,测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=com.xiaojian.dao.MyDao@3d3fcdb0}
com.xiaojian.dao.MyDao@3d3fcdb0

Process finished with exit code 0

如上,在MyService这个对象中,它内部的mydao是3d3fcdb0,而我们IOC容器中本身的MyDao这个对象为3d3fcdb0,所以我们在MyService中通过@Autowired注解注入的MyDao是成功的。

2.1.2、@Autowired@Bean对比

2.1.2.1、修改MyDao数据访问层

MyDao:

package com.xiaojian.dao;

import org.springframework.stereotype.Repository;

//名字默认是类名的小写首字母的方式
@Repository
public class MyDao {

    //此处默认为1
    private String label = "1";

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return "MyDao{" +
                "label='" + label + '\'' +
                '}';
    }
}

2.1.2.2、修改MainConfigOfAutowired配置类

MainConfigOfAutowired:

package com.xiaojian.config;

import com.xiaojian.dao.MyDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {

    //此处是我们在配置类中添加的一个Bean,此处我们命名为myDao2,与MyService中@Autowired注入的mydao1区分开来。
    @Bean("myDao2")
    public MyDao myDao(){
        MyDao myDao=new MyDao();
        myDao.setLabel("2");
        return myDao;
    }
}

我们在此类中添加一个bean的注册,目的在于看看我们在MyService类文件中通过@Autowired注解注入的MyDao是系统配置类的还是bean注册的。

2.1.2.3、修改测试类

我们修改Test_MainConfigOfAutowired测试类。

Test_MainConfigOfAutowired:

package com.xiaojian.test;

import com.xiaojian.config.MainConfigOfAutowired;
import com.xiaojian.dao.MyDao;
import com.xiaojian.service.MyService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test_MainConfigOfAutowired {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

        //看看myservice这个对象里面注入的mydao的信息
        MyService myService = applicationContext.getBean(MyService.class);
        System.out.println(myService);

        applicationContext.close();

    }
}

2.1.2.4、测试运行

运行Test_MainConfigOfAutowired配置类。

测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}

Process finished with exit code 0

如上,控制台打印出了MyService中的通过@Autowired注解注入的MyDao是来自MyDao这个配置类来的,而不是来自@Bean注解注入进来的。

2.1.1.5、总结:

  1. 系统默认优先按照类型去容器中找到对应的组件,找到就给他赋值;
  2. 当系统有多个相同类型的组件的时候,我们通过@Autowired注解注入的内容,是系统通过配置类注入进IOC的对象,而不是通过@Bean注入的内容。

如果将MyService中的MyDao属性改成mydao2,那么系统通过@Autowired注解注入的mydao2就是通过@Bean注入进IOC中的内容。

    @Autowired
    private MyDao myDao2;
  1. 当系统找到多个相同类型的组件的时候,我们将属性的名称作为组件的id去容器中查找,因为通过类型去查找,我们会查找出多个,所以无法查找。
  2. (重要!)自动装配的时候,我们默认一定要将属性值赋值好,否则会报错,因为系统找不到IOC容器中有bean,所以一定要赋值好。

如果存在没赋值好的时候,我们可以将@Autowired注解的required属性设置为false来解决这个问题。设置这个属性后,如果没有赋值好,此处也没有问题,就是不会将此注解标注的mydao装配到类中。

    @Autowired(required = false)

2.1.3、@Qualifier注解指定装配

我们除了用上面方法装配组件,我们可以通过@Qualifier指定需要装配的组件的id,而不是使用属性名。

2.1.3.1、修改MyService服务层

我们修改MyService类文件,将需要自动装配的mydao这个属性添加注解@Qualifier

MyService:

package com.xiaojian.service;

import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Qualifier("myDao2")   //此处通过@Qualifier指定装配myDao2,也就是指定装配通过@Bean注册的组件。
    @Autowired
    private MyDao myDao;


    @Override
    public String toString() {
        return "MyService{" +
                "myDao=" + myDao +
                '}';
    }
}

2.1.3.1、测试运行

我们运行测试类Test_MainConfigOfAutowired,测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}

Process finished with exit code 0

如上,我们通过注解@Qualifier指定自动配置中注入的内容的来源,此处就是来自IOC容器中通过@Bean注册的bean对象。

2.1.4、@Primary注解

让spring进行自动装配的时候,默认使用首选的bean(如果使用了@Qualifier注解指定了,那么就装配其指定的bean对象)。

2.1.4.1、修改MainConfigOfAutowired配置类

我们将MainConfigOfAutowired配置类中的bean添加注解@Primary,将其设置为首选的bean的配置。

MainConfigOfAutowired:

package com.xiaojian.config;

import com.xiaojian.dao.MyDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {

    //此处添加@Primary注解,将其设置为首选的bean注册
    @Primary
    @Bean("myDao2")
    public MyDao myDao(){
        MyDao myDao=new MyDao();
        myDao.setLabel("2");
        return myDao;
    }
}

2.1.4.2、修改MyService服务层

package com.xiaojian.service;

import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class MyService {

//    @Qualifier("myDao2")
//    @Autowired(required = false)
    //此处还原成最原先的,不添加其他的任何注解
    @Autowired
    private MyDao myDao;


    @Override
    public String toString() {
        return "MyService{" +
                "myDao=" + myDao +
                '}';
    }
}

2.1.4.3、测试运行

运行测试类Test_MainConfigOfAutowired,测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}

Process finished with exit code 0

如上,系统的控制台打印除了label=2这个,说明我们MyService中通过注解@Autowired自动配置的MyDao是通过@Primay注解注册的bean对象。

2.2、@Resource自动注入(Java规范注解)

2.2.1、修改MyService服务层

package com.xiaojian.service;

import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class MyService {

//    @Qualifier("myDao2")
//    @Autowired(required = false)
//    @Autowired
    @Resource    //此处添加@Resource
    private MyDao myDao;


    @Override
    public String toString() {
        return "MyService{" +
                "myDao=" + myDao +
                '}';
    }
}

2.3.2、测试运行

运行测试类Test_MainConfigOfAutowired,运行结果如下:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}

Process finished with exit code 0

如上,系统给MyService中添加了@Resource注解的mydao属性自动注入了通过@Repository注入到IOC容器中的bean对象,而不是通过@Bean注解注入到IOC容器中的bean对象。

2.3.3、总结

@Resource注解使用总结:

  1. @Resource可以实现自动装配的功能,但是其默认按照组件名称装配。
  2. 没有能够支持@Primary注解的功能,也没有支持@Autowired(required=false)的功能
  3. 其默认按照@Repository注解注入到IOC容器中的对象,而不是通过@Bean注解注入到IOC容器中的bean对象。
  4. 我们可以通过@Resource(name="xxxx")来指定装配对象。
    @Resource(name = "myDao2")

2.3、@Inject自动注入(Java规范注解)

@Inject注解的使用功能和@Autowired注解是一样的。

2.3.1、导入相关的依赖

我们想要使用这个注解,必须导入其他的相关的依赖。

    <dependency>
      <groupId>javax.inject</groupId>
      <artifactId>javax.inject</artifactId>
      <version>1</version>
    </dependency>

2.3.2、修改MyService服务层

package com.xiaojian.service;

import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.inject.Inject;

@Service
public class MyService {

//    @Qualifier("myDao2")
//    @Autowired(required = false)
//    @Autowired
//    @Resource(name = "myDao2")
    @Inject  //此处使用@inject注解来自动注入
    private MyDao myDao;

    @Override
    public String toString() {
        return "MyService{" +
                "myDao=" + myDao +
                '}';
    }
}

2.3.3、测试运行

2.3.3.1、配置类的bean方法上添加@primary注解

(因为我在MainConfigOfAutowired中没有改变,所以在bean对象的创建上面,我还是添加了@primary注解)

运行测试类Test_MainConfigOfAutowired,测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}

Process finished with exit code 0

如上,此处打印的是label=2,说明此处注入的是MainConfigOfAutowired配置类中的bean方法创建的bean对象,因为我在此方法上面添加了@Primary注解,所以才会打印这个。

2.3.3.2、配置类的bean方法上未添加@Primary注解

运行测试类Test_MainConfigOfAutowired,测试结果:

D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}

Process finished with exit code 0

如上,此处打印的是label=1,说明此处注入的是@Repository注解注入的对象。

猜你喜欢

转载自blog.csdn.net/dh12313012/article/details/85129862