软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 架构设计 -> spring(4) -> 正文阅读
架构设计 最新文章
Opengl教程之读取obj并绘制在picturecontro
读《企业应用架构模式》第五章并发
StepbyStepintoSpring(IOC)
设计模式(2)用例图之一
使用实体组件系统(ECS)开发”吃方块”游戏实
编程学习之简单工厂模式与策略模式
Invalidprojectdescription.
基于Redis实现分布式消息队列(2)
《开源框架那点事儿15》:借船下海还是造船
原型模式——浅复制和深复制

[架构设计]spring(4)

  2016-04-02 20:54:57

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  
360图书馆 论文大全 母婴/育儿 软件开发资料 网页快照 文字转语音 购物精选 软件 美食菜谱 新闻中心 电影下载 小游戏 Chinese Culture
生肖星座解梦 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图 中国文化英文 多播视频 装修知识库
2017-1-23 14:36:19
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --