软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> spring(4) -> 正文阅读

[架构设计]spring(4)


spring的核心容器实现了IOC,其目的主要是为了提供一种无侵入式的框架。要了解spring的核心,首先要从bean了解开始,
然后在了解BeanFactory和AppliactionContext。
1,什么是Bean
Bean是描述java组件软件的模型,java模型中,通过Bean可以无限扩充java程序的功能,通过Bean的配置,可以快速生成
java程序应用,提高代码的重复利用率,减少程序的代码的冗余。
2,Bean的基础知识
(1)Bean的标识(id和name)
先就一个实例,spring配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<value>测试</value>
		</property> 
	</bean>
</beans>
从上面的实例代码可以看到,在spring的配置文档中,一个bean有一个id。这个id在管理Bean的BeanFactory或AppliactionContext中必须是唯一的标识,
因为在代码中通过BeanFactory或ApplicationContext中获取Bean实例时,都是通过它来作为唯一索引的。当然,我们也可以使用Bean的name,把配置的
文件的Bean的id换成name如下:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean name="sayHello" class="com.lanhuigu.spring.action.HelloWorld">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<value>测试</value>
		</property> 
	</bean>
</beans>
当你测试程序时,效果一样。既然两者都能用,让我们比较一下两者的区别:
A.id属性允许指定一个Bean的id,XML解析器能够对其进行一些额外的校验,比如唯一性校验。当你有两个Bean的id一样,XML解析器会提示你不能有
两个一样的Bean的id,在开发时就能发现错误,但是如果用的是Bean的name属性,XML解析器是不会告诉你有两一样的Bean的name,只有在
程序运行期才会发现错误。
B.用name有个特点,当name想写多个值时,中间可以用‘,’或';'号隔开,而id就不行,还是XML解析器的校验过不去,因为Bean的设计目的是唯一的。
看看name多个值取别名的实际用法:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean name="sayHello;testHello" class="com.lanhuigu.spring.action.HelloWorld">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<value>测试</value>
		</property> 
	</bean>
</beans>
看看name的属性值"sayHello;testHello"表示代码运用时可以通过其中一个作为索引获取对象实例,看看代码示例:
package com.lanhuigu.spring.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lanhuigu.spring.action.HelloWorld;

public class TestHelloWorld {
	@Test
	public void testMyHelloWorld(){
		//1.读取spring初始化的配置文件
		ApplicationContext acxt = 
				new ClassPathXmlApplicationContext("/applicationContext.xml");
		//2.根据bean获取ISayHello实现类对象
		HelloWorld hello = (HelloWorld) acxt.getBean("sayHello");
		HelloWorld helloTwo = (HelloWorld) acxt.getBean("testHello");
		//3.调用接口方法
		System.out.println(hello.getMsg());
		System.out.println(helloTwo.getMsg());
	}
}
在代码运用中,通过sayHello,testHello均可获取实例应用于程序。
综上所述,Bean的设计原则是一个bean对应一个唯一实例,一个唯一标识对应一个唯一实例,而name可能会出现多个标识对应一个实例,
以及XML解析器在编程时对name属性缺少必要校验,而对id属性能够做到严谨校验,所以在spring配置Bean时,我们一般选择使用Bean的id属性。
(2)Bean的类(class)
说完了Bean的id,name属性,还得再了解一下class,在配置文件中,我们看到bean的id属性后面跟了个class属性,这个用来干啥的,有啥用?
<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld">
spring配置中,class主要用于指明bean的来源,也就是bean的实际路径,应用程序在根据bean的id获取实例时,获取的实例就是class的类。
值得注意的是class路径写全了,是哪个包下的哪个类,不要只是写个类名,比如写成这样:
<bean id="sayHello" class="HelloWorld">
代码在获取实例时,不知道这个类是啥,你得指明了是从何而来,否则报错如下,告诉你在根据bean的id索引sayHello实例化时,找不到实例类:
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [HelloWorld] for bean with name 'sayHello' defined in class path resource [applicationContext.xml]; nested exception is java.lang.ClassNotFoundException: HelloWorld
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1141)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:758)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:422)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.lanhuigu.spring.test.TestHelloWorld.testMyHelloWorld(TestHelloWorld.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
    at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
    at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: HelloWorld
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:211)
    at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:385)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1138)
    ... 31 more
(3)scope的使用
在spring中,Bean有两种部署模式,分别为singleton和non-singleton(也称为property)模式,spring默认情况下为singleton模式。
*如果spring的Bean被定义成singleton模式,那么就是有一个共享的实例存在,所有对这个Bean的请求都会返回这个唯一的实例。
实际配置: scope='singleton'
*如果spring的Bean被定义成non-singleton模式,那么每次对Bean的请求都会创建一个新的Bean实例,也就是每次都new一个实例。
实际配置:scope="property"
设置成singleton模式实例:
spring配置:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld" scope="singleton">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<value>测试</value>
		</property> 
	</bean>
</beans>
代码测试:
package com.lanhuigu.spring.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lanhuigu.spring.action.HelloWorld;

public class TestHelloWorld {
	@Test
	public void testMyHelloWorld(){
		//1.读取spring初始化的配置文件
		ApplicationContext acxt = 
				new ClassPathXmlApplicationContext("/applicationContext.xml");
		//2.根据bean获取ISayHello实现类对象
		HelloWorld hello = (HelloWorld) acxt.getBean("sayHello");
		HelloWorld helloTwo = (HelloWorld) acxt.getBean("sayHello");
		System.out.println(hello==helloTwo);//比较是否为相同对象
		//3.调用接口方法
		//System.out.println(hello.getMsg());
	}
}
运行结果为true说明为共享对象,每次获取唯一实例,我们可以把singleton替换成prototype,非singleton模式,测试比较对象结果为false,
证明不是同一个对象,是每次调用时创建的实例对象。
(4)对于null的处理
在spring中对于属性配置控制有两种方式:
<value>null</value>或<null/>,对于这两种方式配置null效果一样,实例:
<value>null</value>方式:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld" scope="prototype">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<value>null</value>
		</property> 
	</bean>
</beans>
<null/>方式:
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld" scope="prototype">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<null/>
		</property> 
	</bean>
</beans>
两者效果一样。
(5)depends-on依赖使用
初始化某个Bean之前,先初始化另外一个Bean,通过depends-on依赖实现。
<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for JPetStore's business layer.
  - Contains bean references to the transaction manager and to the DAOs in
  - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:aop="http://www.springframework.org/schema/aop"
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 定义一个id为sayHello的bean,
	通过spring配置文件变换实现类,实现不同的功能,无需修改别的程序 -->
	<bean id="sayHello" class="com.lanhuigu.spring.action.HelloWorld" 
		scope="prototype" depends-on="testDependsOn">
		<!-- 将变量msg值依赖注入 -->
		<property name="msg">
			<null/>
		</property> 
	</bean>
	<bean id="testDependsOn">
		<property name="test">
			<value>test depents-on</value>
		</property>
	</bean>
</beans>
每次初始化sayHello之前,先强制初始化testDependsOn。
......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-02 20:54:52  
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-16 21:25:55
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --