java 自动扫描_详解spring自动扫描包

本文介绍了Spring的组件自动扫描机制,它能自动在类路径下找到标记了@Component、@Service、@Controller、@Repository的类,简化XML配置。通过配置开启扫描并指定基包,可以管理组件。同时,文章探讨了@Service、@Repository、@Component注解的用法,以及如何指定bean的初始化和销毁方法。最后,展示了如何通过@PostConstruct和@PreDestroy注解实现bean的生命周期管理。
摘要由CSDN通过智能技术生成

配置文件

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

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

它的作用和在XML文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

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">

其中这个配置隐式注册了多个对注解进行解析处理的处理器,包括该配置注册的处理器,也就是说写了配置,就不用写配置了,此外base-package为需要扫描的包(含子包)。

注解

@Service用于标注业务层组件、 @Controller用于标注控制层组件(如Struts2中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

本文是建立在@Autowire注解与自动装配的案例基础上的。

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

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">

一个实例

然后使用@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控制台打印:

d3fcf41d4d2d4a236f351493b4d2a736.png

如果我们想使用按指定名称获取,可将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控制台打印:

ba61b5d35eb573162fb5d626976154fb.png

我们前面学过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控制台打印:

4175bf5f0d195be78a5e4453326c1380.png

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控制台会打印:

4ab67f810c33dc34388a41f49cce7f5d.png

总结

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值