spring(4)------Bean的基础

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。

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。

设计模式(2)用例图之一 - 2016-04-03 15:04:58

导言 用例 简介 定义 用例模型 用例理解 用例例子 参与者执行者 定义 参与者角色和用户区别 主要参与者和次要参与者区别 主要参与者和次要参与者的实例 对参与者建模 人类参与者 外部系统参与者 输入设备参与者输入输出设备参与者 计时器参与者 注意 参与者之间的泛化继承关系 如何识别执行者 思路 辨别谁是参与者 导言 为了说明用例图,我们将先介绍用例的定义,然后介绍用例图的相关内容,比如参与者、次要参与者等等。 用例 简介 在用例建模方法中,功能性需求参与者(系统的用户)和用例来描述。 参与者 另可称为
这两天,开始学习mybatis,有点感觉,分享一下,在这里要感谢一号门博客  链接:http://www.yihaomen.com/article/java/426.htm 首先项目示例图给大家看一下: applicationContext.xml类: ?xml version="1.0" encoding="utf-8"? beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001
上一节说过,libevent提供六种bufferevent类型,后面会详细分析其中的两个:bufferevent_sock和bufferevent_async.下面是bufferevent的详细定义: struct bufferevent { /** Event base for which this bufferevent was created. */ struct event_base *ev_base; /** Pointer to a table of function pointers to
1. 背景 目前公司对外开放了一个云服务平台,提供一些功能供商户接入使用。整个项目的架构是基于Spring + MyBatis的。另外,商户端的服务接口是基于SOAP WebService的,这部分使用CXF实现。 安全方面采用了Spring Security,可以对商户提供证书认证或密码认证。但是出于安全考虑,目前只开放了证书认证。为了使用证书认证商户,我们创建了一个自签名的CA,用来生成商户使用的客户端证书。在验证上,使用Nginx验证客户端证书是否是指定CA产生的。另外,为了防止被作废的证书(例如给

Spring + Mybatis配置多数据库 - 2016-04-02 18:04:01

目前有两种思路: 1.动态切换数据源,需要自定义一个数据源类继承自 AbstractRoutingDataSource抽象类, 这种方式有弊端,如果是并发系统中,当你把数据源改了,系统中所有的操作数据源都改了,即使你立马再改回去,还是有风险; 2.建立两套数据源,在spring加载Mapper时关联不同的数据源。 以下仅介绍第二种方式: (1)新建两套数据源: 数据源一: ?xml version="1.0" encoding="UTF-8"?beans xmlns="http://www.springf
模块参数 很多情况下,我们期望通过参数来控制我们的驱动的行为,比如由于系统的不同,而为了保证我们驱动有较好的移植性,我们有时候期望通过传递参数来控制我们驱动的行为,这样不同的系统中,驱动可能有不同的行为控制。 为了满足这种需求,内核允许对驱动程序指定参数,而这些参数可在加载驱动的过程中动态的改变 参数的来源主要有两个 使用 insmod/modprobe ./xxx.ko 时候在命令行后直接给出参数; modprobe命令装载模块时可以从它的配置文件 /etc/modprobe.conf 文件中读取参数值
文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 ise14.7 DBF板 Day4/PCIETest 2016.03.31 lutianfei none 参考资料: Spartan 6 PCIE_V2.4 真教程(一) Spartan 6 PCIE_V2.4 真教程(二) 菜鸟5小时速成FPGA_PCIE设计高手教程.pdf ug671_V6_IntBlock_PCIe.pdf PCI+EXPRESS体系结构导读.pdf 一、PIO模式 PIO模式 是一种通过CPU执行I/O端口指令来

Linux 下多线程排序的实现 - 2016-04-02 18:04:31

对于计算密集型的任务,如果能采用合理的多线程处理,能够大大的提升计算效率。这篇博文实现了多线程排序,同时讲解了一些需要注意的问题。 首先,说一下总体的思路:将元素分成n段,使用快速排序多个线程并行处理。最后需要等待这些线程都将分段排好序之后,进行类似归并排序的过程。 这样时间复杂度算下来是(假设我是4核的机器) O(n+n/4log(n/4)),比O(nlogn)大概快了一倍的样子。(请带入数值具体计算) 先来介绍一下 pthread_barrier系列函数。 函数原型:#include pthread.
【编者按】一直想申请一个免费的托管空间,国内找了一圈sinaapp还算差强人意,但是对于python不以安装C extension的包,而且SAE的一整套流程用起来感觉很不爽,而openshift的平台的工作流更适合一般开发人员的思维模式(我是针对Python,其他语言没有试过没有发言权),鉴于国内关注得还比较少,我把自己注册到开发的经验记录下来,希望对需要的人有所帮助。 Openshift简介 Openshift是RedHat公司的一款平台云产品,openshift.com是由RedHat公司维护的一个
http://blog.csdn.net/hellochina15/article/details/7253350 本文介绍如何在Windows 7操作系统和Virtual PC 2007虚拟机上安装Hello China操作系统,Hello China的版本是V1.75。对于Windows XP等非Windows 7操作系统,由于不能直接支持虚拟硬盘,不能按照本文介绍的方法安装Hello China的GUI功能,但是可以安装内核和基于字符界面的shell。 HelloChina在Virtual PC上的