Bean配置信息是Bean的元数据信息,它由一下4个方面组成:java
Bean元数据信息在Spring容器中的内部对应物是一个个BeanDefinition造成的Bean注册表,Spring实现了Bean元数据信息内部表示和外部定义之间的解耦。正则表达式
Spring1.0仅支持基于XML的配置,Spring2.0新增基于注解配置的支持,Spring3.0新增基于Java类配置的支持,Spring4.0则新增给予Groovy动态语言配置的支持。spring
<?xml version="1.0" encoding="utf-8" ?> <beans (1)xmlns="http://www.springframework.org/schema/beans" (2)xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:(3)context=(4)"http://www.springframework.org/schema/context" xsi:(5)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.xsd"> </beans>
xmlns:namespace-prefix="namespaceURI"
,其中namespace-prefix为自定义前缀,只要在这个XML文档中保证前缀不重复便可;namespaceURI是这个前缀对应的XML Namespace的定义。xsi:schemaLocation定义了XML Namespace和对应的 XSD(Xml Schema Definition)文档的位置的关系。它的值由一个或多个URI引用对组成,两个URI之间以空白符分隔(空格和换行都可)。第一个URI是定义的 XML Namespace的值,第二个URI给出Schema文档的位置,Schema处理器将从这个位置读取Schema文档,该文档的targetNamespace必须与第一个URI相匹配。例如:数据库
<beans xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
这里表示Namespace为http://www.springframework.or...://www.springframework.org/schema/context/spring-context.xsd。express
<!--id不能够配置多个: context.getBean("myBean1, myBean2")--> <bean class="com.ankeetc.spring.MyBean" id="myBean1, myBean2"/> <!--context.getBean("myBean1") == context.getBean("myBean2")--> <bean class="com.ankeetc.spring.MyBean" name="myBean1, myBean2"/>
,
分割;id和name能够都为空,此时则能够经过获取全限定类名来获取Bean。public class MyBeanFactory { public static MyBean createMyBean() { return new MyBean(); } }
<bean id="myBean" class="com.ankeetc.spring.MyBeanFactory" factory-method="createMyBean"/>
public class MyBeanFactory { public MyBean createMyBean() { return new MyBean(); } }
<bean id="myBeanFactory" class="com.ankeetc.spring.MyBeanFactory"/> <bean id="myBean" factory-bean="myBeanFactory" factory-method="createMyBean"/>
<beans>元素提供了一个default-autowire属性能够全局自动匹配,默认为no。<bean>元素提供了一个指定自动装配类型的autowire属性,能够覆盖<beans>元素的default-autowire属性,该属性有以下选项:缓存
自动装配类型 | 说明 |
---|---|
no | 显式指定不使用自动装配。 |
byName | 若是存在一个和当前属性名字一致的 Bean,则使用该 Bean 进行注入。若是名称匹配可是类型不匹配,则抛出异常。若是没有匹配的类型,则什么也不作。 |
byType | 若是存在一个和当前属性类型一致的 Bean ( 相同类型或者子类型 ),则使用该 Bean 进行注入。byType 可以识别工厂方法,即可以识别 factory-method 的返回类型。若是存在多个类型一致的 Bean,则抛出异常。若是没有匹配的类型,则什么也不作。 |
constructor | 与 byType 相似,只不过它是针对构造函数注入而言的。若是当前没有与构造函数的参数类型匹配的 Bean,则抛出异常。使用该种装配模式时,优先匹配参数最多的构造函数。 |
default | 根据 Bean 的自省机制决定采用 byType 仍是 constructor 进行自动装配。若是 Bean 提供了默认的构造函数,则采用 byType;不然采用 constructor 进行自动装配。 |
<util:list></util:list> <util:set></util:set> <util:map></util:map>
<bean class="com.ankeetc.spring.MyBean" id="myBean"> <property name="prop" value="prop"/> </bean>
<bean class="com.ankeetc.spring.MyBean" id="myBean"> <constructor-arg type="java.lang.String" index="0" value="abc"/> <constructor-arg type="int" index="1" value="10"/> </bean>
<![CDATA[]]>
节或者转义序列<ref>元素能够经过如下三个属性引用容器中的其余Bean:session
<bean id="prop" class="com.ankeetc.spring.Prop"> <property name="value" value="1314"/> </bean> <bean id="myBean" class="com.ankeetc.spring.MyBean"> <property name="prop"> <!--内部Bean即便提供了id、name、scope也会被忽略--> <bean id="prop" class="com.ankeetc.spring.Prop"> <property name="value" value="520"/> </bean> </property> </bean>
<null/>
表明null值prop.value
,并且支持多层级联属性NullValueInNestedPathException
public class MyBean { // 必须初始化 private Prop prop = new Prop(); public Prop getProp() { return prop; } public void setProp(Prop prop) { this.prop = prop; } }
<bean id="myBean" class="com.ankeetc.spring.MyBean"> <property name="prop.value" value="1314"/> </bean>
<bean id="parentBean" class="com.ankeetc.spring.MyBean"> <property name="list"> <list> <value>1314</value> </list> </property> </bean> <bean id="myBean" class="com.ankeetc.spring.MyBean" parent="parentBean"> <property name="list"> <list merge="true"> <value>520</value> </list> </property> </bean>
类型 | 说明 |
---|---|
singleton | 在Spring IoC容器中仅存在一个Bean实例,Bean以单实例的方式存在 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例 |
request | 每次HTTP请求都会建立一个新的Bean,该做用域仅适用于WebApplicationContext环境 |
session | 同一个HTTP session共享一个Bean,不一样的HTTP session使用不一样的Bean,该做用域仅适用于WebApplicationContext环境 |
globalSession | 同一个全局Session共享一个Bean,通常用于Portlet环境,该做用域仅适用于WebApplicationContext环境 |
见后续章节app
见后续章节ide
因为实例化Bean的过程比较负责,可能须要大量的配置,这是采用编码的方式多是更好的选择。Spring提供了FactoryBean工厂类接口,用户能够实现该接口定制实例化Bean的逻辑。当配置文件中<bean>的class属性配置的是FactoryBean的子类时,经过getBean()返回的不是FactoryBean自己,而是getObject()方法所返回的对象,至关因而FactoryBean#getObject()代理了getBean()方法。函数
T getObject() throws Exception;
:返回由FactoryBean建立的Bean实例,若是isSingleton()返回的是true,该实例会放到Spring容器的实例缓存池中。Class<?> getObjectType();
:返回该FactoryBean建立的Bean的类型boolean isSingleton();
:建立的Bean是singleton的仍是prototype/** * 实现,分割的方式配置 KFCCombo 属性 */ public class KFCFactoryBean implements FactoryBean<KFCCombo> { private String prop; public String getProp() { return prop; } // 接受,分割的属性设置信息 public void setProp(String prop) { this.prop = prop; } // 实例化KFCCombo public KFCCombo getObject() throws Exception { KFCCombo combo = new KFCCombo(); String[] props = prop.split(","); combo.setBurger(props[0]); combo.setDrink(props[1]); return combo; } public Class<?> getObjectType() { return KFCCombo.class; } // true则放进容器缓存池,false则每次都调用getObject()方法返回新的对象 public boolean isSingleton() { return false; } }
<bean id="combo" class="com.ankeetc.spring.KFCFactoryBean"> <property name="prop" value="ZingerBurger, PepsiCola"/> </bean>
@Component:在Bean的实现类上直接标注,能够被Spring容器识别
@Repository:用于对DAO实现类进行标柱
@Service:用于对Service实现类进行标注
@Controller:用于对Controller实现类进行标注
Spring提供了一个context命名空间,用于扫描以注解定义Bean的类。
<!--生命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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package="com.ankeetc.spring"/> </beans>
**/*.class
,即基包下的全部类类别 | 示例 | 说明 |
---|---|---|
annotation | com.ankeetc.XxxAnnotation | 全部标注了XxxAnnotation的类。该类型采用目标类是否标志了某个注解进行过滤。 |
assignable | com.ankeetc.XxService | 全部继承或扩展XXXService的类。该类型采用目标类是否继承或者扩展了某个特定类进行过滤 |
aspectj | com.ankeetc..*Service+ | 全部类名以Service结束的类及继承或者扩展他们的类。该类型采用AspectJ表达式进行过滤 |
regex | com.ankeetc.auto..* | 全部com.ankeetc.auto类包下的类。该类型采用正则表达式根据目标类的类名进行过滤 |
custom | com.ankeetc.XxxTypeFilter | 采用XxxTypeFilter代码方式实现过滤规则,该类必须实现org.springframework.core.type.TypeFilter接口 |
<!-- 仅扫描标注了@Controller注解的类--> <context:component-scan base-package="com.ankeetc.spring" use-default-filters="false"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
@Component public class KFCCombo { @Autowired private PepsiCola cola; @Autowired private Map<String, Cola> colaMap; @Autowired private List<ZingerBurger> burgerList; private ZingerBurger burger; @Autowired public void setBurger(@Qualifier(value = "zingerBurger") ZingerBurger burger) { this.burger = burger; } public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"classpath:/beans.xml"}); KFCCombo combo = context.getBean(KFCCombo.class); } } interface Cola {} @Order(value = 1) @Component class CocaCola implements Cola {} @Order(value = 2) @Component class PepsiCola implements Cola {} @Component(value = "zingerBurger") class ZingerBurger { }
public class Main { public static void main(String[] args) { // (1)能够直接设置容器启动要加载的类 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DaoConfig.class); // (2)能够向容器中注册新的类 ((AnnotationConfigApplicationContext) applicationContext).register(ServiceConfig.class); // (3)注册了新的类要记得refresh ((AnnotationConfigApplicationContext) applicationContext).refresh(); } } @Configuration class DaoConfig { @Bean public String getStr() { return "1314"; } } @Configuration @Import(DaoConfig.class) // (4)能够经过@Import将多个配置类组装称一个配置类 class ServiceConfig { }
标注了@Configureation的配置类自己也是一个bean,它能够被Spring的<context:component-scan>扫描到。若是但愿将此配置类组装到XML配置文件中,经过XML配置文件启动Spring容器,仅在XML文件中经过<context:component-scan>扫描到相应的配置类便可。
<context:component-scan base-package="com.ankeetc.spring" resource-pattern="Config.class"/>
在标注了@Configuration的配置类中,能够经过@ImportResource引入XML配置文件。
@Configuration @ImportResource("classpath:beans.xml") public class Config { }