Spring -- 入门,装备集合,自动装配,分散装配,自定义编辑器

1. 概要

struts2:web
hibernate:持久化
spring:业务层.管理bean的,容器.List Map Set.

体验spring:
	1.创建java项目.
	2.引入spring的类库.
		${spring解压目录}/dist/spring.jar
		${spring解压目录}/lib/jakarta-commons/commons-logging.jar
	2'.创建业务类.
		/**
		 * GreetingService
		 */
		public class GreetingService {
			private String greeting ;//get/set
			private String greeting2 ;//get/set
			
			/* byeService */
			private ByeService bs ;//get/set
			public void  sayGreeting(){
				bs.sayBye();
			}
		}

		/**
		 * ByeService
		 */
		public class ByeService {
			private String bye ;

			public String getBye() {
				return bye;
			}

			public void setBye(String bye) {
				this.bye = bye;
			}
			
			
			public void sayBye(){
				System.out.println(bye);
			}
		}
	3.配置spring的配置文件.src/applicationContext.xml
		schema:${spring解压目录}\docs\reference\html_single\index.html\3.2.1.1
		<?xml version="1.0"?>
		<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-2.5.xsd">
			<!-- 欢迎服务 -->
			<bean id="greetingService" class="cn.itcast.spring.service.GreetingService">
				<property name="greeting">
					<value>hello world</value>
				</property>
				<property name="greeting2" value="tom" />
				<property name="bs" ref="byeService" />
			</bean>
			<!-- 欢送服务 -->
			<bean id="byeService" class="cn.itcast.spring.service.ByeService">
				<property name="bye">
					<value>later</value>
				</property>
			</bean>
		</beans>
	4.创建app.
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		GreetingService gs = (GreetingService) ac.getBean("greetingService");
		gs.sayGreeting();
		gs.sayGreeting2();
		
		ByeService bs = (ByeService) ac.getBean("byeService");
		bs.sayBye();

spring:
	ioc: inverse of control,反转控制.获得依赖对象的方式被反转了. (不要手动new bean对象)
		 1.new.(spring负责对象实例化)
		 2.组装对象的出发点是反的(相对于bean的依赖关系是反的).
		 DI:dependency injection,依赖注入.  <==> ioc
	aop: aspect oriented program,面向方面编程.

oop:面向对象编程.

soa:

GreetingService gs = new ...();

gs.setByeService(bs);

ByeService bs = new ...();
gs.sayGreeting();

BeanFactory:实例化bf时,不会实例化任何bean,只有getBean的时候,才实例化相关的bean.节省资源.
ApplicationContext:实例化ac时,实例化单例bean.
懒汉式:
public class A{
	private A(){}

	public static A instance = null ;
	public static A getInstance(){
		if(instance == null){
			instance = new A();
		}
		return instance ;
	}
}

饿汉式:
	public static A instance = new A();

spring单利bean,对应的bean的叫做prototype(原型bean).

ac.getBean("bs"); == new ByeService();

生命周期:
	1.new
	2.set DI
	3.BeanNameAware:bean名关注
	4.BeanFactoryAware:bean工厂关注
	5.BeanPostProcessor.beforeInitialization();
	5'.调用InitializingBean.afterPropertySet()方法.
	6.init-method
	7.BeanPostProcessor.afterInitialization();

spring()框架. 代码的入侵.
1.高侵入性
2.低侵入
3.非侵入行

jee:jsp servlet jpa jta ejb(enterprise javabean),jndi
pojo:plain old java object.


BeanDefinition:bean的定义,spring对bean的信息的封装.
Root bean: class [cn.itcast.spring.service.GreetingService]; scope=singleton; abstract=false; lazyInit=false;
autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; 
factoryMethodName=null; initMethodName=ini; destroyMethodName=release; defined in class path resource 
[applicationContext.xml]

Class clazz = Class.forName("cn.itcast.spring.service.GreetingService");
clazz.newInstance();

scope:prototype singleton request session global_session

<struts>
	<package namepace extends="">

在ide下注册spring中的schema文件.
	${spring解压目录}\dist\resources\*.xsd.
	
List Set Map:
Properies:
.properties

<hibernate-mapping>
	<class name table lazy>
		<id >
			<generator class="" />
		</id>
		<property name="age" column access="field">
	</class>

spring通过构造函数参数注入依赖强化依赖关系.

自动装配:
	1.byName:按照名称自动装配,寻找和bean的属性名相一致的bean的id.(bean必须有空的构造,通过set方法注入)
	2.byType:按照属性的类型来自动装配,如果找到多个,抛异常.(bean必须有空的构造,通过set方法注入)
	3.constructor:按照构造函数参数的类型自动装配,如果找不到或者找多个,都抛异常.
	4.autodetact:自动检测,在(2)和(3)之间选择一个	5.no.
	6.default,跟<beans default-autowire属性>保持一致.

分散配置:
	把需要在上下文硬编码的属性拿到外部的属性文件中定义,让上下文从外部文件提取值.

自定义编辑器:
	将字符串转换成相应的对象,


2. Spring中bean的生命周期, 及其工作流程

bean被载入到容器中时,他的生命周期就开始了。bean工厂在一个bean可以使用前完成很多工作:

1).容器寻找bean的定义信息并实例化。

2).使用依赖注入,springbean定义信息配置bean的所有属性。

3).bean实现了BeanNameAware接口,工厂调用BeansetBeanName()方法传递beanID

4).bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

5).BeanPostProcessorbean关联,则它们的postProcessBeforeInitialization()方法被调用。

6).bean指定了ini-method方法、,它将被调用。

7).最后,若有BeanPostProcessorbean关联,则它们的postProcessAfterInitialization()方法被调用、。

 

示例代码一 BeanPostProcessor 注册bean后处理器,能给所有bean做初始和收尾工作,等效于在xml文件中配置init-method="ini"  destroy-method="release"。

如果bean构造时 需要调用有参的构造函数,可以在constructor-arg 中配置。

ByeService.java , javabean

public class ByeService {
	private String bye ;
	public String getBye() {
		return bye;
	}
	public void setBye(String bye) {
		this.bye = bye;
	}
	public void sayBye(){
		System.out.println(bye);
	}
}


GreetingService.java, javabean

public class GreetingService implements BeanNameAware,BeanFactoryAware{
	private String greeting ;
	private String greeting2 ;
	
	/* byeService */
	private ByeService bs ;
	
	public GreetingService(ByeService bs){
		this.bs = bs ;
		System.out.println("Constructor: new GreetingService()");
	}
	public GreetingService(String str1,String str2){
		System.out.println("1111");
	}
	public GreetingService(String str1,Integer str2){
		System.out.println("2222");
	}
	public GreetingService(String str1,int str2){
		System.out.println("3333");
	}
	public GreetingService(int str1,String str2){
		System.out.println("4444");
	}
	
	/**
	 * beannameAware,注入bean的id
	 */
	public void setBeanName(String name) {
		System.out.println("BeanNameAware:setBeanName() : " + name);
	}
	
	/**
	 * bean工厂关注
	 */
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("BeanFactoryAware:setBeanFactory() : " + beanFactory);
	}

	public ByeService getBs() {
		return bs;
	}

	public void setBs(ByeService bs) {
		this.bs = bs;
		System.out.println("DI:setBs() : " + bs);
	}

	public String getGreeting() {
		return greeting;
	}

	public void setGreeting(String greeting) {
		this.greeting = greeting;
		System.out.println("DI:setGreeting() : " + greeting);
	}
	
	public void sayGreeting(){
		bs.sayBye();
	}
	public void sayGreeting2(){
		System.out.println(greeting2);
	}

	public String getGreeting2() {
		return greeting2;
	}

	public void setGreeting2(String greeting2) {
		this.greeting2 = greeting2;
		System.out.println("DI:setGreeting2() : " + greeting2);
	}
	
	/**
	 * 定制初始化方法
	 */
	public void ini(){
		System.out.println("ini");
	}
	
	/**
	 * 定制销毁方法
	 */
	public void release(){
		System.out.println("release");
	}
}


MyBeanPostProcessor.java, bean的后处理器

public class MyBeanPostProcessor implements BeanPostProcessor {

	/**
	 * 后处理
	 */
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("BeanPostProcessor:after:" + beanName);
		return bean;
	}

	/**
	 * 之前处理
	 */
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("BeanPostProcessor:before:"+beanName);
		return bean;
	}
}


applicationContext.xml 配置文件

<?xml version="1.0"?>
<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-2.5.xsd">
    <!-- 欢迎服务 -->
    <bean id="greetingService" class="cn.itcast.spring.service.GreetingService"
        scope="singleton"
        init-method="ini"
        destroy-method="release">
        <constructor-arg index="1" type="java.lang.String" value="12" />
        <constructor-arg index="0" type="int" value="24" />
        <property name="greeting">
            <value>hello world</value>
        </property>
        <property name="greeting2" value="tom" />
        <property name="bs" ref="byeService" />
    </bean>
    <!-- 欢送服务 -->
    <bean id="byeService" class="cn.itcast.spring.service.ByeService">
        <property name="bye">
            <value>later</value>
        </property>
    </bean>
    
    <!-- 注册bean后处理器 -->
    <bean id="myBeanPostProcessor" class="cn.itcast.spring.beanprocessor.MyBeanPostProcessor" />
</beans>


App.java

public class App {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"applicationContext.xml");//src下 不需要加全路径
		GreetingService gs = (GreetingService) ac.getBean("greetingService");
		gs.sayGreeting();
		gs.sayGreeting2();
		ByeService bs = (ByeService) ac.getBean("byeService");
		bs.sayBye();
		((ClassPathXmlApplicationContext)ac).destroy();
	}
}

 

3.  集合装配bean

单例和原型模式 prototypesingletonrequest sessionglobal-session ,spring中的bean缺省情况下是单例模式。始终返回一个实例。若想返回不同的实例的话需要定义成原型模式。beansingleton属性告诉上下文该bean是否为单例的。缺省为true。若为false的话,为原型bean

<bean id="foo" class="...Foo" singleton="false"/>

<! spring2.5 -->

<bean scope="prototype|single|..">

 
自动装配:

   <bean id="foo" class="...Foo" autowire="autowire type">

有四种自动装配类型:

1.byName:寻找和属性名相同的bean,若找不到,则装不上。

2.byType:寻找和属性类型相同的bean,找不到,装不上,找到多个抛异常。

3.constructor:查找和bean的构造参数一致的一个或多个bean,若找不到或找到多个,抛异常。按照参数的类型装配 

4.autodetect:(3)(2)之间选一个方式。不确定性的处理与(3)(2)一致。(选择标准:是否有含参的构造函数,没有则是byType)

       <bean id="bar" class="Bar" autowire="byName"/>

        <!-- spring2.5 -->

      @Autowired

      <bean class="... AutowiredAnnotationBeanPostProcessor">

示例代码二: (通过util定义集合bean需要手动添加 spring-util-2.5.xsd)

PopSet.java, javabean

public class PopSet {
	private String[] ss ;
	private List list ;	
	private Set set ;	
	private Map map ;	
	private Properties prop ;
         .....省略 get set方法
}


popSet.xml 配置文件, java bean中的 prop 对应到配置文件中用标签<prop> </prop>配置。

<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:util="http://www.springframework.org/schema/util" 
    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-2.5.xsd 
                        http://www.springframework.org/schema/util 
                        http://www.springframework.org/schema/util/spring-util-2.5.xsd ">
    <bean id="popSet" class="cn.itcast.spring.popset.PopSet">
        <property name="ss">
            <list>
                <value>1</value>
                <value>tom</value>
            </list>
        </property>
        <property name="list" ref="myList" />
        <property name="set">
            <set>
                <value>1</value>
                <value>tom</value>
                <ref bean="byeService"/>
                <ref bean="byeService"/>
                <bean class="cn.itcast.spring.service.ByeService">
                    <property name="bye" value="kk" />
                </bean>
                <bean class="cn.itcast.spring.service.ByeService">
                    <property name="bye" value="kk" />
                </bean>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="key001" value="tom" />
                <entry key="key002" value-ref="byeService" />
                <entry key="key003">
                    <bean class="cn.itcast.spring.service.ByeService" />
                </entry>
            </map>
        </property>
        <property name="prop">
            <props>
                <prop key="key001">tom</prop>
                <prop key="key002">tom1</prop>
                <prop key="key003">tom2</prop>
            </props>
        </property>
    </bean>
    
    <bean id="byeService" class="cn.itcast.spring.service.ByeService">
        <property name="bye" value="over" />
    </bean>
    
    <!-- 通过util定义集合bean -->
    <util:list id="myList">
        <value>1</value>
        <value>2</value>
        <value>tom</value>
        <ref bean="byeService"/>
        <ref bean="byeService"/>
        <bean class="cn.itcast.spring.service.ByeService">
            <property name="bye" value="kk" />
        </bean>
        <bean class="cn.itcast.spring.service.ByeService">
            <property name="bye" value="kk" />
        </bean>
    </util:list>
</beans>


App.java

public class App {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"cn/itcast/spring/popset/popSet.xml");
		ac.getBean("popSet");
	}
}


4.分散装配

将配置文件分成几个分散的配置文件。如配置数据库的 jdbc.properties文件。使用占位符变量代替bean装配文件中的硬编码配置。占位符采${variable}形式。

定制属性编辑器 , 如下利用自定义的编辑器能将 省市县装配到homeAddress对应的属性中去。

<property name="homeAddress">
            <value>湖南省.长沙市.宁乡县.花明楼镇</value>
</property>

 

示例代码三:

Address.java, javabean

public class Address {
	private String province;
	private String city;
	private String street;
	private String zipCode;
	......省略 set get方法
}

Scatter.java, javabean

public class Scatter {
	private String driverClass ;
	private String url ;
	private String username ;
	private String password ;
	
	private Address comAddress ;//公司地址
	private Address homeAddress ;//家庭地址


}

jdbc.properties 分散配置的 prop文件

jdbc.driverclass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

AddressEditor.java 自定义编辑器

public class AddressEditor extends PropertyEditorSupport {

	public void setAsText(String text) throws IllegalArgumentException {
		if(text != null && text.length() > 0){
			String[] ss = text.split("\\.");
			if(ss != null && ss.length > 3){
				Address a = new Address();
				a.setProvince(ss[0]);
				a.setCity(ss[1]);
				a.setStreet(ss[2]);
				a.setZipCode(ss[3]);
				//将转换成的地址对象设置给相应的属性上
				setValue(a);
			}
			else{
				setValue(null);
			}
		}
		else{
			setValue(null);
		}
	}	
}


scatter.xml 配置文件

<?xml version="1.0"?>
<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd ">
    <!-- 分散配置(属性占位符配置器)
    <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:cn/itcast/spring/scatter/jdbc.properties</value>
            </list>
        </property>
    </bean>
     -->
     
    <!-- 自定义编辑器配置器 -->
    <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
        <!-- 自定义编辑器集 -->
        <property name="customEditors">
            <map>
                <entry key="cn.itcast.spring.scatter.Address">
                    <bean class="cn.itcast.spring.editor.AddressEditor" />
                </entry>
            </map>
        </property>
    </bean>
     
    <bean id="scatter" class="cn.itcast.spring.scatter.Scatter">
        <property name="driverClass" value="${jdbc.driverclass}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!--  -->
        <property name="comAddress">
            <bean class="cn.itcast.spring.scatter.Address">
                <property name="province" value="jilin" />
                <property name="city" value="cc" />
                <property name="street" value="${jdbc.url}" />
            </bean>
        </property>
        <property name="homeAddress">
            <value>${jdbc.driverclass}.cc.renmin.139988</value>
        </property>
    </bean>
    
    <!-- 分散配置,加载分散配置的文件 -->
    <context:property-placeholder location="classpath:cn/itcast/spring/scatter/jdbc.properties"/>
</beans>


App.java

public class App {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext(
				"cn/itcast/spring/scatter/scatter.xml");
		ac.getBean("scatter");
	}
}




 

posted @ 2014-03-04 13:58  今晚打酱油_  阅读(323)  评论(0编辑  收藏  举报