Java bean之容器调用机制
作为java程序控制层数据交互部分的缓存,java bean的加载方式如上图所示,Spring容器根据xml <bean>标签的写入、java中的@configuration、@bean、@autowrite注解等信息,将相关的java bean的信息注册在容器的注册表中。之后Spring容器会根据注册表的信息将注册表中的bean类进行实例化,并将实例化后的bean对象与java程序中的bean实例绑定放入容器中,形成一个bean的缓存池,当java应用程序需要调用bean实例时,Spring容器会直接根据索引在缓存池中调用相应的bean实例。
1、bean的定义
bean的配置有三种方式:1、在xml文件中配置,2、使用注解定义并自动装配,3、基于java类提供Bean定义信息
基于xml文件的配置
对于基于XML的配置,Spring 2.0以后使用Schema的格式,使得不同类型的配置拥有了自己的命名空间,是配置文件更具扩展性。
①默认命名空间:它没有空间名,用于Spring Bean的定义;
②xsi命名空间:这个命名空间用于为每个文档中命名空间指定相应的Schema样式文件,是标准组织定义的标准命名空间;
③aop命名空间:这个命名空间是Spring配置AOP的命名空间,是用户自定义的命名空间。
命名空间的定义分为两个步骤:第一步指定命名空间的名称;第二步指定命名空间的Schema文档样式文件的位置,用空格或回车换行进行分分隔。
在Spring容器的配置文件中定义一个简要Bean的配置片段如下所示:
一般情况下,Spring IOC容器中的一个Bean即对应配置文件中的一个<bean>。其中id为这个Bean的标识,通过容器的getBean()即可获取对应的Bean,在容器中起到定位查找的作用,是外部程序和Spring IOC容器进行交互的桥梁。class属性指定了Bean对应的实现类。getBean的入参包括name、requiredType、args;其中name不可为空,对应的是xml文件中<bean>的id,requiredType可为空,对应的是<bean>标签的class,标明这个bean的类型,传入格式为类对象形式,即 类名.class形式。
使用注解配置信息启动spring容器
Spring提供了一个context的命名空间,它提供了通过扫描类包以应用注解定义Bean的方式:
<?xml version="1.0" encoding="UTF-8" ?> <!--①声明context的命名空间--> <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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <!--②扫描类包以应用注解定义的Bean--> <context:component-scan base-package="com.baobaotao.anno"/> <bean class="com.baobaotao.anno.LogonService"></bean> <!-- context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ --> <!-- context:component-scan base-package="com.baobaotao"> <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Dao"/> <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Service"/> <context:exclude-filter type="aspectj" expression="com.baobaotao..*Controller+"/> </context:component-scan --> </beans>
在①处声明context命名空间,在②处即可通过context命名空间的component-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。
如果仅希望扫描特定的类而非基包下的所有类,你们可以使用resource-pattern属性过滤特定的类,如下所示:
< context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ >
这里我们将基类包设置为com.baobaotao,默认情况下resource-pattern属性的值为"**/*.class",即基类包里的所有类。这里我们设置为"anno/*.class",则Spring仅会扫描基包里anno子包中的类。
Bean注入
传统方式下是在XML中配置,此时分别有属性注入、构造函数注入和工厂方法注入
属性注入
属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。
属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
package com.baobaotao.anno; import org.springframework.beans.factory.BeanNameAware; public class LogonService implements BeanNameAware{ private LogDao logDao; private UserDao userDao;
private String value;public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setLogDao(LogDao logDao) { this.logDao = logDao; }
public void setValue(String value) { this.value = value; }public LogDao getLogDao() { return logDao; } public UserDao getUserDao() { return userDao; }
public String getValue() {
return value;}
}
bean.xml配置
<?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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-autowire="byName" > <bean id="logDao" class="com.baobaotao.anno.LogDao"/> <bean id="userDao" class="com.baobaotao.anno.UserDao"/> <bean id="logonService" class="com.baobaotao.anno.LogonService"> <property name="logDao" ref="logDao"></property>