> 文档中心 > 详解Spring IOC属性注入、Bean的作用域和@Autowired、@Qualifier、@Resource区别

详解Spring IOC属性注入、Bean的作用域和@Autowired、@Qualifier、@Resource区别

目录

1.Spring IOC创建对象的两种方式

2.Bean作用域

3.属性注入

3.1 普通装配

3.2 自动装配(xml格式)

3.3 自动装配(基于注解

总结:


本文主要是讲解一下个人对spring的一些认识!

在讲这三者的区别之前,我想先简单回顾一下Spring IOC 操作管理Bean;

先来一个简单的案例:

applicationContext.xml

           
//加载配置文件ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");//获取资源 UserService userService = ctx.getBean("userService1",UserService.class);

如上所示就是简单的将类交给Spring管理,再由spring创建对象的过程;

Bean管理指的是两个操作:1.Spring创建对象,2.Spring注入属性;

Bean管理操作有两种方式:1.基于xml配置文件方式实现;2.基于注解方式实现;

1.Spring IOC创建对象的两种方式

IOC底层就是对象工厂;

1.BeanFactory(将案例的ApplicationContext更改为BeanFactory也是可以的);

        IOC容器的基本实现,Spring内部接口,一般不提供给开发使用;

2.ApplicationContext (就是案例的那种)

        BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员使用;

3.两者的区别:

        BeanFactory,加载配置文件的时候,不会创建对象,只有我们在获取对象的时候,也就是案例中调用getBean方法,才会去创建,属于动态工厂;

        ApplicationContext,加载配置文件的时候,就会把所有的在配置文件中配置了bean标签的类创建出对象,属于静态工厂;

显然,一般我们把耗时耗性能的操作在服务器启动的时候就做了,所以,一般使用ApplicationContext方式创建对象,也就在加载配置文件的时候就把对象/实例创建出来;

两个接口的关系:

显然,ApplicationContext是BeanFactory的子接口,在BeanFactory的基础上做了增强;

2.Bean作用域

就是设置bean是多实例还是单实例;

如何测试多实例还是单实例:

如上代码所示:我们只要多次调用 getBean()方法,看对象是不是同一个对象即可;

我们主要谈两种:singleton(单实例)和prototype(多实例)

1.bean标签的scope属性可设置作用域;

2.在类上加注解 @Scope("singleton")或者@Scope("prototype")可设置作用域;

scope如果是singleton,即使没getBean(),也会创建对象,即先加载创建,想用就去拿,所以都是拿的同一个对象;

如果是prototype,是当你执行getBean()执行一次,就会创建一个新的对象;

即两种作用域的对象的创建时机不同;默认作用域是singleton;

3.属性注入

比如我们要将StudentServiceImpl类交给Spring管理,并将StudentMapper注入StudentServiceImpl类;

public class StudentServiceImpl {    //属性studentMapper    private StudentMapper studentMapper;    //方法    public void updateStudent(){ Student student = new Student(); student.setSid(1); student.setAge(25); studentMapper.updateByPrimaryKeySelective(student);    }}

3.1 普通装配

1.需要在application.xml里面写bean标签,如下所示:

   

2.如果我们要在java里面使用StudentServiceImpl类的对象

//加载配置文件ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");//创建对象StudentServiceImpl studentServiceImpl = (StudentServiceImpl)ctx.getBean("studentService");//调用对象的方法访问数据库studentServiceImpl.updateStudent();

这样,我们就通过Spring获取到了一个StudentServiceImpl类的对象,也就可以调用它的具体方法了;

3.2 自动装配(xml格式)

bean标签中有autowire属性可配置自动装配,autowire属性常用两个值:

byName:根据属性名称注入,这个就要注入bean的id要和类的属性名称一致;

byType:根据类型注入;

按照名称注入:

要给StudentServiceImpl注入StudentMapper,按照名称注入,要求StudentMapper的bean的id和StudentServiceImpl类的属性studentMapper名称一致:

  

按照类型注入:

只要有类型是com.jzcs.mapper.StudentMapper的bean就会被注入;

 

但是如果是如下所示的情况,有两个bean的类型都是com.jzcs.mapper.StudentMapper,这样Spring IOC就不知道具体要注入哪一个,就会报错;

  

3.3 自动装配(基于注解)

首先,将类交给Spring管理,只需要加上注解就可以了:

@Controller、@Service、@Component、@Repository,这几个注解的作用其实都是一样的,都是将类交给Spring管理,这样就不用写bean标签了;

这种情况,我们要注入属性,就有三个注解:

@Autowire:根据属性类型进行自动装配;

比如:@Autowired StudentDao,StudentDao是接口,会自动注入它的实现类,但是如果该接口有多个实现类,那@Autowired按照类型就有问题了;

@Qualifier:根据名称注入,要和@Autowired一起使用;

比如,上面说的情况,如果StudentDao有两个实现类,StudentDaoImpl1 、StudentDaoImpl2,单独使用@Autowired报错,结合@Qualifier使用;

@Servicepublic class StudentService {    @Autowired    @Qualifier(value = "studentDaoImpl1") //按照名称注入studentDaoImpl1    private StudentDao studentDao;    public void updateStudent(){ Student student = new Student(); student.setSid(1); student.setAge(25); studentDao.updateByPrimaryKeySelective(student);    }}

@Resource:既可以根据类型注入,也可以根据名称注入;

写了name属性,就根据名称注入,不写就根据类型注入;

@Resource是javax扩展包中的注解,spring官方更建议我们使用@Autowire和@Qualifier;

注意:bean的名称,一般如果我们不手动给,就会使用类名,首字母小写作为bean的名称;

总结:

上面已经说明了@Autowire、@Qualifier、@Resource三个注解的区别;

我们java中自己写一个类,里面的属性包含另一个类,总体就是类,我们要创建一个实例,在单纯的java中,我们需要new 类创建一个该类的对象,这样有强耦合;所以我们呢开发了spring框架,我们将创建好的类,比如...Service/dao等,交给spring管理,比如加注解或者xml里的bean标签;当我们要一个对象并调方法的时候,比如我们要一个service对象,调用里面的处理逻辑的方法,原来就是new Service/dao,现在就直接从spring容器里面获取一个对象,比如@autower等注解;

KTV音响网