zoukankan      html  css  js  c++  java
  • (转)让Spring自动扫描和管理Bean

    http://blog.csdn.net/yerenyuan_pku/article/details/52861403

    前面的例子我们都是使用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>
    • 1
    • 2

    其中<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>
    • 1

    然后使用@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();
        }
    }
    • 1

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

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

    最后,我们修改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();
        }
    
    }
    • 1

    测试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();
        }
    }
    • 1

    这样,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();
        }
    
    }
    • 1
    • 2

    测试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();
        }
    }
    • 1

    意味着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();
        }
    
    }
    • 1

    测试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();
        }
    }
    • 1

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

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

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

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

     
     
  • 相关阅读:
    音频处理之回声消除及调试经验
    音频软件开发中的debug方法和工具
    ZJOI2015地震后的幻想乡
    HEOI2015小L的白日梦
    THUWC2017随机二分图
    PKUWC Slay The Spire
    dp的一些计划
    鸡汤征集贴
    弱菜的各种模板
    洛谷P4902乘积
  • 原文地址:https://www.cnblogs.com/telwanggs/p/6913301.html
Copyright © 2011-2022 走看看