您的位置:首页 > 编程语言 > Java开发

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

2014-03-04 13:58 471 查看
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).使用依赖注入,spring按bean定义信息配置bean的所有属性。

3).若bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递bean的ID。

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

5).若BeanPostProcessor和bean关联,则它们的postProcessBeforeInitialization()方法被调用。

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

7).最后,若有BeanPostProcessor和bean关联,则它们的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

单例和原型模式
prototype、singleton、request session、global-session ,spring中的bean缺省情况下是单例模式。始终返回一个实例。若想返回不同的实例的话需要定义成原型模式。bean的singleton属性告诉上下文该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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: