详解spring自动扫描包

 更新时间:2018年06月12日 14:08:38   作者:qq_36098284  
这篇文章主要介绍了spring自动扫描包的相关知识,本文通过实例相结合的形式给大家介绍的非常详细,感兴趣的朋友跟随脚本之家小编一起看看吧

配置文件

前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些组件采用XML的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。

Spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进Spring容器中管理。

它的作用和在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"
 xmlns:context="http://www.springframework.org/schema/context"
 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-4.2.xsd">
 <context:component-scan base-package="cn.itcast" />
</beans>

其中<context:component-scan base-package="cn.itcast" />这个配置隐式注册了多个对注解进行解析处理的处理器,包括<context:annotation-config/>该配置注册的处理器,也就是说写了<context:component-scan base-package="cn.itcast" />配置,就不用写<context:annotation-config/>配置了,此外base-package为需要扫描的包(含子包)。

注解

@Service用于标注业务层组件、 @Controller用于标注控制层组件(如Struts2中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
本文是建立在@Autowire注解与自动装配的案例基础上的。

我们首先将Spring的配置文件改为:

<?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" 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-4.2.xsd">
 <context:component-scan base-package="cn.itcast" />
</beans>

一个实例

然后使用@Service注解标注PersonServiceBean类,如下:

@Service
public class PersonServiceBean implements PersonService {
 private PersonDao personDao;
 public void setPersonDao(PersonDao personDao) {
  this.personDao = personDao;
 }
 @Override
 public void save() {
  personDao.add();
 }
}

使用@Repository注解标注PersonDaoBean类,如下:

@Repository
public class PersonDaoBean implements PersonDao {
 @Override
 public void add() {
  System.out.println("执行PersonDaoBean中的add()方法");
 }
}

最后,我们修改SpringTest类的代码为:

public class SpringTest {
 @Test
 public void instanceSpring() {
  AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 
  PersonService personService = (PersonService) ctx.getBean("personServiceBean");
  PersonDao personDao = (PersonDao) ctx.getBean("personDaoBean");
  System.out.println(personService);
  System.out.println(personDao);
  ctx.close();
 }
}

测试instanceSpring()方法,可看到Eclipse控制台打印:

这里写图片描述

如果我们想使用按指定名称获取,可将PersonServiceBean类的代码修改为:

@Service("personService")
public class PersonServiceBean implements PersonService {
 private PersonDao personDao;
 public void setPersonDao(PersonDao personDao) {
  this.personDao = personDao;
 }
 @Override
 public void save() {
  personDao.add();
 }
}

这样,SpringTest类的代码应改为:

public class SpringTest {
 @Test
 public void instanceSpring() {
  AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 
  PersonService personService = (PersonService) ctx.getBean("personService");
  System.out.println(personService);
  ctx.close();
 }
}

测试instanceSpring()方法,可看到Eclipse控制台打印:

这里写图片描述

我们前面学过Spring管理的bean的作用域,我们就能知道以上Spring管理的两个bean的作用域默认是singleton。当然了,我们也可以更改Spring管理的bean的作用域,如将PersonServiceBean类的代码改为:

@Service("personService") @Scope("prototype")
public class PersonServiceBean implements PersonService {
 private PersonDao personDao;
 public void setPersonDao(PersonDao personDao) {
  this.personDao = personDao;
 }
 @Override
 public void save() {
  personDao.add();
 }
}

意味着Spring管理的PersonServiceBean这个bean的作用域变成prototype了,这时我们将SpringTest类的代码修改为:

public class SpringTest {
 @Test
 public void instanceSpring() {
  AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 
  PersonService personService1 = (PersonService) ctx.getBean("personService");
  PersonService personService2 = (PersonService) ctx.getBean("personService");
  System.out.println(personService1 == personService2);
  ctx.close();
 }
}

测试instanceSpring()方法,可看到Eclipse控制台打印:

这里写图片描述

prototype作用域本来就意味着每次从Spring容器获取bean都是新的对象嘛。

若是通过在classpath路径下自动扫描方这种式把组件纳入Spring容器中管理,如何指定bean的初始化方法和销毁方法呢?这时我们就需要用到两个注解:@PostConstruct和@PreDestroy。为了试验,我们将PersonServiceBean类的代码修改为:

@Service("personService")
public class PersonServiceBean implements PersonService {
 private PersonDao personDao;
 @PostConstruct
 public void init() {
  System.out.println("初始化资源");
 }
 @PreDestroy
 public void destroy() {
  System.out.println("销毁、关闭资源");
 }
 public void setPersonDao(PersonDao personDao) {
  this.personDao = personDao;
 }
 @Override
 public void save() {
  personDao.add();
 }
}

接下来还要将SpringTest类的代码修改为:

public class SpringTest {
 @Test
 public void instanceSpring() {
  AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 
  PersonService personService = (PersonService) ctx.getBean("personService");
  ctx.close();
 }
}

这样,测试instanceSpring()方法,Eclipse控制台会打印:

这里写图片描述

如要查看源码,可点击让Spring自动扫描和管理Bean进行下载

总结

以上所述是小编给大家介绍的spring自动扫描包,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 重新认识Java的System.in

    重新认识Java的System.in

    今天小编就为大家分享一篇关于重新认识Java的System.in,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • java构建Stream流的多种方式总结

    java构建Stream流的多种方式总结

    Java 8引入了Stream流作为一项新的特性,它是用来处理集合数据的一种函数式编程方式,本文为大家整理了多种java构建Stream流的方式,希望对大家有所帮助
    2023-11-11
  • Java设计模式之观察者模式

    Java设计模式之观察者模式

    本文详细讲解了Java设计模式之观察者模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 详解Spring如何整合Mybatis

    详解Spring如何整合Mybatis

    今天给大家带来的是关于Java的相关知识,文章围绕着Spring如何整合Mybatis展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Spring Boot 多个定时器冲突问题的解决方法

    Spring Boot 多个定时器冲突问题的解决方法

    这篇文章主要介绍了Spring Boot 多个定时器冲突问题的解决方法,实际开发中定时器需要解决多个定时器同时并发的问题,也要解决定时器之间的冲突问题,本文通过问题场景重现给大家介绍的非常详细,需要的朋友参考下吧
    2022-05-05
  • java基础javeSE程序逻辑控制语法

    java基础javeSE程序逻辑控制语法

    主要讲解Java中程序的逻辑控制语句包括 Java中的输入输出方式 顺序结构循环结构等,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-09-09
  • SpringBoot+Quartz实现动态定时任务

    SpringBoot+Quartz实现动态定时任务

    这篇文章主要为大家详细介绍了springBoot+Quartz实现动态定时任务,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • Java 中的Printstream介绍_动力节点Java学院整理

    Java 中的Printstream介绍_动力节点Java学院整理

    PrintStream 是打印输出流,它继承于FilterOutputStream。接下来通过本文给大家介绍Java 中的Printstream,需要的朋友参考下吧
    2017-05-05
  • 关于idea刚打开时疯狂报错的问题

    关于idea刚打开时疯狂报错的问题

    这篇文章主要介绍了关于idea刚打开时疯狂报错的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • 使用System.exit()来优雅地终止SpringBoot项目的代码示例

    使用System.exit()来优雅地终止SpringBoot项目的代码示例

    System.exit() 方法是 Java 中用于退出程序的方法,它接受一个整数参数,通常被用来指示程序的退出状态,本文给大家介绍了如何使用System.exit()来优雅地终止SpringBoot项目,需要的朋友可以参考下
    2024-08-08

最新评论