一、bean上面的配置
Service1类如下,其他service类以此类推,具体都是放在AbstractBeanDefinition的属性中
public class Service1 {
public Service1(){
System.out.println("service1 init");
}
public void deal(){
System.out.println("service1 deal");
}
}
1、id:唯一标识
2、name:别名,如果id不存在则用name,在getBean的时候可以用别名来获取
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="service1" name="aliasService1,aliasService2" class="com.myspring.service.Service1"/>
</beans>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
Service1 service1= (Service1)context.getBean("aliasService1");
service1.deal();
}
3、class:类名
4、parent:父类,如果子类未指定属性则沿用父类的
子BeanDefinition继承父BeanDefinition的scorp、constructor 、property 、method overrides,并添加新配置。子BeanDefinition会覆盖父子BeanDefinition的配置有:initialization method、destroy method、static factory method settings。
5、singleton:已弃用,直接配在scope属性中
6、scope:作用域,支持配置singleton(单例) ,prototype(原型),request,session,global session,后面三个都是web中的bean配置,
1).request是与请求有关,为每个请求创建一个bean,请求结束bean就销毁
2).session等同web中session的生命周期
3).global session:用于portlet的web应用中(未再深入研究啥是portlet的web应用)
7、abstract:抽象类,如果去掉abstract配置,则两个类的无参构造方法都会调用,加上后只会调用service1
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="service1" name="aliasService1,aliasService2" class="com.myspring.service.Service1"/>
<bean id="service2" class="com.myspring.service.Service2" abstract="true"/>
</beans>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
// Service1 service1= (Service1)context.getBean("aliasService1");
// service1.deal();
}
8、lazy-init:是否懒加载,枚举值有true,false,default,只加载配置文件的时候不会初始化service3,将注释去掉则会调用service3的无参构造方法
<!--配置文件中增加以下配置-->
<bean id="service3" class="com.myspring.service.Service3" lazy-init="true"/>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
// Service3 service3= (Service3)context.getBean("service3");
}
9、autowire:自动装配,枚举值有no,byName,byType,constructor,autodetect,default,需要注意的是必须要有set方法,然后类不能在构造函数中初始化,byName可解决多个关联类不同name的情况。如果是default,则取beans的配置
<bean id="service4" class="com.myspring.service.Service4" autowire="byType"/>
public class Service4 {
private Service1 service1;
public Service1 getService1() {
return service1;
}
public void setService1(Service1 service1) {
this.service1 = service1;
}
public Service4(){
}
public void deal(){
service1.deal();
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
Service4 service4 = (Service4) context.getBean("service4");
service4.deal();
}
10、depends-on:依赖的类,会比当前类先加载,注解还可用于方法上,这样的话service1的构造方法先先调用。
<bean id="service5" class="com.myspring.service.Service5" depends-on="service1"/>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
}
11、autowire-candidate:设置某个类作为自动注入的类时是否作为候选类,跟primary及autowire=“byName”都是差不多的用法
12、primary:自动注入时指定首选类
<bean id="service1" name="aliasService1,aliasService2" class="com.myspring.service.Service1" primary="true"/>
<bean id="service11" class="com.myspring.service.Service1"/>
13、init-method:类初始化调用
<bean id="service7" class="com.myspring.service.Service7" init-method="initMethod"/>
public class Service7 {
public void initMethod(){
System.out.println("initMethod");
}
}
14、destroy-method:容器销毁时调用,跟初始化差不多的用法,调用容器的registerShutdownHook方法会被调用
15、factory-method:工厂类方法
16、factory-bean:实例化工厂类,调用工厂类静态方法与非静态方法的区别,非静态类需要实例化
<!--静态的不需要配置factorybean-->
<bean id="service8" class="com.myspring.service.Service8Factory" factory-method="createService8"/>
public class Service8Factory {
public static Service8 createService8(){
return new Service8();
}
}
<!--非静态的配置factorybean-->
<bean id="service8" factory-bean="service8Factory" factory-method="createService8NotStatic"/>
<bean id="service8Factory" class="com.myspring.service.Service8Factory" ></bean>
public class Service8Factory {
public static Service8 createService8(){
return new Service8();
}
public Service8 createService8NotStatic(){
return new Service8();
}
}
二、子节点配置
1、meta:元数据,在子节点中定义之后能通过getAttribute方法取到,实际是放在AttributeAccessorSupport的attributes属性中,属性类型为LinkedHashMap,value值为BeanMetadataAttribute
<bean id="service9" class="com.myspring.service.Service9">
<meta key="myName" value="service9"></meta>
</bean>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
BeanDefinition definition = ((ClassPathXmlApplicationContext) context).getBeanFactory().getBeanDefinition(
"service9");
System.out.println(definition.getAttribute("myName"));
}
2、lookup-method:主要实现原理是cglib动态代理,为Service10生成动态代理类,返回bean属性配置的实例对象,我这里配置的是单例的,实际使用场景应该是原型模式。具体以LookupOverride对象的形式放在AbstractBeanDefinition中的methodOverrides属性中,methodOverrides属性为MethodOverrides类型,最终存在MethodOverrides的overrides中,overrides类型为CopyOnWriteArraySet<MethodOverride>。
<bean id="service10" class="com.myspring.service.Service10">
<lookup-method name="getService" bean="service1"></lookup-method>
</bean>
public abstract class Service10 {
public abstract Service1 getService();
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my-spring.xml");
Service10 service10 = (Service10)context.getBean("service10");
Service1 service1 = service10.getService();
service1.deal();
}
3、replaced-method,替换调用的方法,调用会调用无参构造器初始化原有的方法,在调用时才替换。具体以ReplaceOverride对象的形式放在AbstractBeanDefinition中的methodOverrides属性中,methodOverrides属性为MethodOverrides类型,最终存在MethodOverrides的overrides中,overrides类型为CopyOnWriteArraySet<MethodOverride>。
<bean id="service11" class="com.myspring.service.Service11">
<replaced-method name="deal" replacer="service11Replacer"></replaced-method>
</bean>
<bean id="service11Replacer" class="com.myspring.service.Service11Replacer"></bean>
public class Service11 {
public Service11(){
System.out.println("service11 init");
}
public void deal(){
System.out.println("service11 deal");
}
}
public class Service11Replacer implements MethodReplacer {
@Override
public Object reimplement(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("我来替换了");
return null;
}
}
4、constructor-arg:构造器配置,ref属性或是value或除description和meta以外的属性只能出现一个。具体以ConstructorArgumentValues.ValueHolder对象的形式放在AbstractBeanDefinition中的constructorArgumentValues属性中,constructorArgumentValues属性为ConstructorArgumentValues类型,最终存在ConstructorArgumentValues的indexedArgumentValues中,indexedArgumentValues类型为LinkedHashMap。
1)ref属性:最终以RuntimeBeanReference对象存在ConstructorArgumentValues.ValueHolder中的value属性中
2)value属性:最终以TypedStringValue对象存在ConstructorArgumentValues.ValueHolder中的value属性中
3)子元素属性,支持以下配置
- 自定义属性
- bean:最终以BeanDefinitionHolder对象的形式存ConstructorArgumentValues.ValueHolder中的value属性中
- ref:最终以RuntimeBeanReference对象存在ConstructorArgumentValues.ValueHolder中的value属性中
- idref:最终以RuntimeBeanNameReference对象存在ConstructorArgumentValues.ValueHolder中的value属性中
- value:最终以TypedStringValue对象存在ConstructorArgumentValues.ValueHolder中的value属性中
- null:最终以TypedStringValue对象存在ConstructorArgumentValues.ValueHolder中的value属性中
- array:支持子节点,递归解析,最终以ManagedArray
对象存在ConstructorArgumentValues.ValueHolder中的value属性中, - list:支持子节点,递归解析,最终以ManagedList
对象存在ConstructorArgumentValues.ValueHolder中的value属性中, - set:支持子节点,递归解析,最终以ManagedSet
对象存在ConstructorArgumentValues.ValueHolder中的value属性中, - map:子节点中支持<entry>标签,<entry>下面支持<key>标签,<entry>的属性ref、key与子标签<key>三者取其一,<key>标签下又支持子节点,最终以ManagedMap
对象存在ConstructorArgumentValues.ValueHolder中的value属性中,
<bean id="service12" class="com.myspring.service.Service12">
<constructor-arg index="0" type="java.lang.String" value="aaa"></constructor-arg>
<constructor-arg index="1" type="java.util.Map">
<map>
<entry value="123" key="aaa"></entry>
<entry value="456" key="bbb"></entry>
</map>
</constructor-arg>
<constructor-arg index="2" type="java.lang.String" value="ccc"></constructor-arg>
</bean>
5、property:属性注入。类中必须要提供set方法。具体以PropertyValue对象的形式放在AbstractBeanDefinition中的propertyValues属性中,propertyValues属性类型为MutablePropertyValues,最终存在MutablePropertyValues的propertyValueList中,propertyValueList类型为ArrayList
<bean id="service13" class="com.myspring.service.Service13">
<property name="a" value="111"></property>
</bean>
public class Service13 {
private String a;
public void setA(String a) {
this.a = a;
System.out.println(a);
}
}
6、qualifier:具体以AutowireCandidateQualifier对象的形式放在AbstractBeanDefinition中的qualifiers属性中,qualifiers属性类型为Map<String, AutowireCandidateQualifier>