- 浏览: 35868 次
- 性别:
- 来自: 上海
文章分类
最新评论
在Spring中,对象间的协作是通过IoC机制完成的。
反向控制也叫依赖注入(Dependency Injection,DI),简单来说就是将JavaBean需要的
对象通过配置文件加载进来。
Spring提供了两种装配Bean的容器,一是BeanFactoy,另一个是ApplicationContext。
两者做为容器,所有的Bean都应该通过容器装配,而容器也知道自己都装配了哪些Bean。
Bean装配实际上就是让容器知道程序中都有哪些Bean,可以通过以下两种方式实现:
配置文件(最为常用,体现了依赖注入DI的思想)
编程方式(写的过程中向BeanFactory去注册)
ApplicationContext与BeanFactory都是接口,ApplicationContext是由BeanFactory
接口扩展而来,它增强了BeanFactory的功能。
Bean容器能够加载的对象并不一定是严格遵循JavaBeans规范的Java类,任何可实例化的类都
可以通过Spring Bean容器加载进来。通常称这些类为POJO。
要记住,BeanFactory不仅仅只具备实例化Bean的功能,它还知道所有的Bean,可以配置和管理它们。
Spring给出一些BeanFactory的实现类,其中最为常用的是XmlBeanFactory。
1、通过文件系统
Resource res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
2、通过类路径
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
3、通过ApplicationContext加载
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
BeanFactory factory = (BeanFactory) appContext;
sping-frameword-1.2.7-with-dependencies中的dist里面是spring的包
将其中的spring.jar加入工程的类路径里面,下一步是写个javaBean
package bean ;
public class HelloBean
{
public HelloBean
{
System.out.println("init!");
}
private String msg ;
//加上getter和setter方法
};
public class Demo
{
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml") ;
//配置文件放在类路径的根路径下
BeanFactory factory = new XmlBeanFactory(res) ;
//在dist文件夹里面有spring-beans的dtd文档
HelloBean bean = (HelloBean)factory.getBean("hello") ;
//根据xml配置文件中的id号去找bean,然后从这个工厂中取出bean
System.out.println(bean.getMsg());
HelloBean bean1 = (HelloBean)factory.getBean("hello") ;
System.out.println(bean==bean1); //因为配置文件中的singleton设置为true,
//故是单例模式,所以两个bean肯定一样,所以打印true
//只有ApplicationContext才能实现bean的非延迟加载功能,所以要想让bean中的
//"init!"字符串在"before getbean!"字符串之前显示的话,那么首先必须得是单例模式,
//然后还得设置lazy-init="false",才可以做到,如果singleton="false"的话,是无法
//做到非延迟加载的!可以通过下面的代码来验证,看"before getbean!"和"init!"这两个
//字符串出现的先后顺序就一目了然了。
ApplicationContext factory = new ClassPathXmlApplicationContext("bean.xml");
System.out.println("before getbean!");
HelloBean bean2 = (HelloBean)factory.getBean("hello");
}
}
配置文件bean.xml:
将<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
拷贝进去……
<beans>
//singleton属性表明容器的bean是否使用单例模式……
//默认情况下,beanFactory就是延迟加载的
<bean id="hello" class="bean.HelloBean" singleton="true"
lazy-init="false">
<property name="msg">
<value>Hello,Spring!</value>
</property>
</bean>
</beans>
//上面的配置文件将属性的值注入到bean的属性中,这就是依赖注入的一个例子
//同时将那个javaBean注册到容器中
通常可以通过三种方式装配Bean
通过setter方法
通过构造函数
自动装配
其中,使用setter方法装配Bean是最为常用的。
如下代码的执行结果是什么?
FirstBean bean = (FirstBean)factory.getBean("my");
FirstBean bean1 = (FirstBean)factory.getBean("my");
System.out.println(bean==bean1);
结果依赖于bean元素的singleton属性,如果设置true,则以单例模式加载bean,
则永远指向同一个bean;反之则每次实例化一个。
也即在单例模式下,BeanFactory维护所有的bean
如果想让一个单例模式的bean被清理掉的话,不能简单的将bean置为null,而是必须使用
destroySingletons方法
还有一个destroyBean(String beanName,Object bean)
这两个方法都可以来垃圾回收单例模式中的bean
--------------------------------------------------------------
延迟加载:
如下代码执行的结果是什么?
System.out.println("before loading");
FirstBean bean = (FirstBean)factory.getBean("my");
System.out.println(“after loading”);
在bean的构造函数中,包含:
System.out.println(“bean init”);
结果依赖于bean的lazy-init属性,如果设置为true,则在第一次加载该bean时初始化;
否则在初始化容器时就加载所有bean。
延迟加载仅在bean单例模式下起作用。
-------------------------------------------------------------------------
初始化和清理:
Spring的初始化肯定是在依赖注入(属性设置)全部完成后才去做的。
框架提供的初始化方法肯定是先于我们自己定义的初始化方法的!比如,如果继承了
InitializingBean的话,会有一个这个接口提供的初始化方法,叫做afterPropertySet,
它的执行就是先于你定义的初始化方法的……
同理,DisposableBean接口中也定义了一个清理的方法,这个方法肯定也是先于你定义的
清理方法的!
建议使用你自己定义的初始化和清理方法,不要使用容器提供的,这样可以避免bean被污染!!!
在许多情况下,需要在对象加载后立即初始化资源,而在删除对象前先清理资源
在spring中,提供了两种方式实现初始化和清理工作。
通过设置bean的init-method和destroy-method指定初始与清理方法
通过实现InitializingBean及DisposableBean接口,由容器在加载与删除bean时自动调用。
//既然定义了一个init方法,所以可以在javaBean中设置下面的初始化方法:
public void init()
{
}
//同样销毁方法也可以类似的定义:
public void destroy()
{
}
//特别注意,如果你想运行上面自定义的destroy方法的话,你必须首先执行
factory.destroySingletons();
//否则不会去执行你上面自定义的destroy方法的!
原型bean在创建之后就脱离了factory的管理,所以呢,对于原型bean,只能初始化,而
不可以清理
<bean id="first" class="mybeans.FirstBean" init-method="init"
destroy-method="destroy" >
<property name="message">
<value>Hi, Rod Johnson</value>
</property>
</bean>
可以通过destroySingletons方法删除所有单例bean
原型bean在创建后即脱离BeanFactory的维护,所以只能调用初始化方法,而不能做清理工作。
===========================================================================
下午课程开始:
public class HelloBean implements BeanNameAware, BeanFactoryAware
{
private BeanFactory factory ;
private String name ;
public void setBeanName(String a)//由BeanNameAware继承来
{
this.name = a ;
}
//由BeanFactoryAware继承而来。
public void setBeanFactory(BeanFactory factory)
throws BeanException
{
this.factory = factory
}
}
-------------------------------------------------------
下面说说编程式加载Bean方式:
XmlBeanFactory提供两种编程方式加载Bean:
registerSingleton和registerBeanDefinition,前者不参与bean生命周期
后者参与bean的生命周期。
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
factory.registerSingleton("bb",new HelloBean());
HelloBean bean = (HelloBean)factory.getBean("bb");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
如果使用BeanDefinition的话
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
//上面这句话告诉Spring自定义的方法名字叫做init,如果不写的话,自定义的
//初始化方法不会执行的。
/*
RootBeanDefinition rbd1 = new RootBeanDefinition(Integer.class);
ContructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbd1.setConstructorArgumentValues(cav);
factory.registerBeanDefinition("aa",rbd1);
System.out.println(factory.getBean("aa"));
*/
factory.registerBeanDefinition("aa",rbd);
HelloBean bean = (HelloBean)factory.getBean("aa");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
老师的关键代码如下:
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
RootBeanDefinition rbdi = new RootBeanDefinition(Integer.class);
ConstructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbdi.setConstructorArgumentValues(cav);
=====================================================================
bean里面的属性是各式各样的,我们上面使用的实体类只是使用了String类型,根本没有考虑
其他的类型
bean装配方式:
通过Setter方法、通过构造函数、自动装配三种方法都可以达到装配Bean的目的。
其中使用setter方法装配Bean是最为常用的。
先说一下setter方法的装配:
setter方法可以装配基本类型、Bean类型、内部bean类型、集合类型、设置空值
所谓Bean类型属性是指这个属性类型是个javaBean,并且这个javaBean必须已经在Spring
中注册过了!
对于基本数据类型,
可以包括八种基本类型以及其包装类
<property name="" value="" />就可以了,不用在意具体类型,Spring会自动转换的。
装配基本类型:
包括八种基本类型及它们的包装类,还有String类型。
不必关心具体类型,spring可以通过反射机制了解到属性的类型信息
可以通过<property>的子元素<value>来设置基本类型的值,也可以通过其属性value来设置,
效果完全相同。
<bean id="first" class="mybeans.FirstBean" >
<property name="message">
<value>Hi, Rod Johnson</value>
</property>
<property name="age" value="1" />
//注意不能同时使用value子元素和value属性
</bean>
--------------------------------------------------------------------------
装配bean类型属性:
只有通过配置文件向容器注册的bean才能通过注入机制设置到其它bean的属性上。
使用<ref>子元素或ref属性设置
Spring即是通过这种方式建立起bean间的依赖关系,实现强大的bean管理功能。
举例说明:
BasicDataSource
引入包commons-dbcp、commons-pool以及commons-collections三个包引入
还有mysql的驱动程序
将BasicDataSource中的setter方法注入Spring中去。
在bean.xml中:
//将BasicDataSource中的setter方法中的对应值设置进去!
<beans>
<bean id="data" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///j2ee"/>
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="course" class="bean.CourseBean">
<property name="dataSource" ref="data"/>
//由于是bean,所以使用ref!
</bean>
</beans>
建立一个Bean,对应数据库中的一个表
public class CourseBean
{
private int id ;
private String name ;
private DataSource dataSource ;
//加入getter和setter方法
public void save()
{
}
}
然后就可以进行一下数据库的操作了……
在main函数中执行下面的代码:
---------------------------------------------------------------
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
CourseBean course = (CourseBean)factory.getBean("course");
//由于数据源和courseBean之间的依赖关系已经通过配置文件给配置好了,所以这里
//只需要得到courseBean,就自然有了数据源的bean了。
course.setName("adsf");
course.save();
-----------------------------------------------------------------
所谓DAO就是既有值,又可以将这个值存入数据库的对象,也就是数据库访问对象
Data Access Object
所谓VO就是仅仅有值,也就是value object,值对象。
上面的这个course就是DAO了。
上面的save方法可以简单的写成下面的样子:
public void save()
{
try
{
Connection con = this.dataSource.getConnection();
String sql = "insert into courses (coursename,period)"+
"values(rtrim(?),rtrim(?))" ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
pstmt.setString(1,this.coursename);
pstmt.setInt(2,this.period.intValue());
pstmt.executeUpdate();
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
======================================================================
如果一个bean在使用前,其某个属性的值必须已经通过注入机制注入,spring可以协助检查这个属性
是否被初始化。
bean的属性dependency-check即用来实现这样的功能,其可选值包括
none --不检查
objects --仅检查bean类型
simple --仅检查基本类型(8种)和String类型
all --全检查
default --默认,不检查
此外,因为可能会调用其它对象的方法,有时一个对象在使用前必须要求另外一个对象已经初始化完成
这种依赖关系可以通过depends-on属性来实现,spring会保证在初始化当前对象前将depends-on
指定的对象也初始化出来。
如果依赖多个对象,使用逗号将它们的名字分开。
内部Bean
<bean id="outer" class="...">
<property name="target">
<bean class="com.mycompany.PersonImpl">
<property name="name">
<value>Tony</value>
</property>
</bean>
</property>
</bean>
----------------------------------------------------
Spring支持以下四种集合的装配:
<list>--java.util.List
<set>--java.util.Set
<map>--java.util.Map
<props>--java.util.Properties
list:
<property name="someList">
<list>
<value>someValue</value>
<ref bean="myDataSource"/>
<list>
<value>anyValue</value>
</list>
</list>
</property>
set:
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource"/>
</set>
</property>
map:
<property name="someMap">
<map>
<entry>
<key><value>yup an entry</value></key>
<value>just some string</value>
</entry>
<entry>
<key><value>yup a ref</value></key>
<ref bean="myDataSource"/>
</entry>
</map>
</property>
props:
<property name="people">
<props>
<prop key="HarryPotter">
The magic property
</prop>
<prop key="JerrySeinfeld">
The funny property
</prop>
</props>
</property>
==========================================================
==========================================================
如果属性没有setter方法的话,需要考虑使用构造方法装配pbean的属性,这就是
构造装配
一般在以下情况使用:
属性没有setter方法,是只读属性
属性只需要设置一次,以后就不会再更改
一般使用构造装配只装配少量属性
注意在构造装配下,构造函数中应该包含有需要装配的属性
比如:
<bean id="i" class="java.lang.Integer">
<constructor-arg value="23" />
</bean>
这就是利用构造函数将Integer注入到容器中去。
Integer i = (Integer)factory.getBean("i");
System.out.println(i);
-----------------------------------------------------
<bean id="first" class="mybeans.FirstBean">
<constructor-arg>
<value>http://www.sohu.com</value>
</constructor-arg>
<constructor-arg>
<value>http://localhost:8080</value>
</constructor-arg>
<property name="age" value="1" />
</bean>
多个参数时使用多个constructor-arg指定,出现次序决定了参数次序,或者使用index属性指定
======================================================
自动装配:
可以通过spring框架自动为bean装配属性。
自动装配只能装配bean类型,即取代ref元素。
使用自动装配只需在bean元素中加入属性autowire,自动装配可被手动装配覆盖。
也可以选择在beans中加入default-autowire属性,为所有bean设置默认自动装配。
“no“-不使用自动装配,spring推荐。
“byName”-依据名称或ID装配bean,如果没有找到,则不装配,可依赖dependency-check
属性检查是否装配。
“byType”-依据类型自动装配,如果存在两个以上同种类型,则抛出异常。
“constructor”-依据当前bean构造函数装配,查找与构造函数参数同类型bean
“autodetect”-自动检测,先通过constructor,再使用byType
Spring是不推荐使用自动装配的,首先是系统开销的问题,还有就是同名的设置可能会导致
意外的问题……
====================================================================
通过BeanFactory获取Bean与直接new一个Bean是完全不同的。
不相同的地方在于:从factory中得到的bean是被注入依赖关系的bean,而new出来的bean
则没有依赖关系,属性是空的。
通过BeanFactory获取的bean能将所有依赖注入到bean中,属性的值会依设置而定。
New出来的bean属性值必须主动设置。
在需要使用spring框架情况下,所有bean都应该由容器来管理。
===================================================================
单例和原型的问题:依赖于singleton参数,true为单例模式。
延迟加载:体现在整个容器初始化的时候立刻加载bean还是等到使用这个bean的时候才加载。
factory.getBean的时候就已经是开始使用bean了,并不一定要访问其中的属性
才算是使用。
只有ApplicationContext才能做到容器初始化的时候立刻加载bean,BeanFactory
是做不到的。
注册bean的时候,name属性是用的别名,id属性标明真名。name一般是在web开发里面去用,name
里面是可以包含一些特殊符号的,用于告诉开发者当前的属性代表什么具体的实际意思。
setter方法、构造函数和自动装配三种装配bean的方式
=====================================================================
ApplicationContext:
ApplicationContext与BeanFactory的作用相类似,都起到装配、管理Bean的作用。
不同的是,ApplicationContext在此基础上增强了BeanFactory的功能,这包括国际化、
加载资源、发布事件等等。
国际化的支持:
Spring提供了两个实现了MessageSource接口的类,它们都在
org.springframework.context.support包中:
ResourceBundleMessageSource使用JFC中标准的java.util.ResourceBundle来操作资源
ReloadableResourceBundleMessageSource 可以在不重启虚拟机的情况下重新加载资源。
ResourceBundleMessageSource是具体的类而且有setter方法,所以可以注入
根据setBasename,
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="bean.res" />
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
这里还需要在bean包下面建立一个资源包res.properties,
在里面写上:
msg=Hello,{0}
public static void main(String[] args)
{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
String s = context.getMessage("msg",new Object[]{"Spring-Hibernate"},new Locale("zh"));
System.out.println(s);
}
这就打印出了“Hello,Spring-Hibernate”
--------------------------------------------------------
假如有多个资源包呢?
比如我又在bean包里面建了一个ress.properties
m=M
那么
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>bean.res</value>
<value>bean.ress</value>
</list>
</property>
</bean>
--------------------------------------------------------
可以通过IOC机制加载资源,如
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>springResource</value>
</property>
</bean>
或者
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
反向控制也叫依赖注入(Dependency Injection,DI),简单来说就是将JavaBean需要的
对象通过配置文件加载进来。
Spring提供了两种装配Bean的容器,一是BeanFactoy,另一个是ApplicationContext。
两者做为容器,所有的Bean都应该通过容器装配,而容器也知道自己都装配了哪些Bean。
Bean装配实际上就是让容器知道程序中都有哪些Bean,可以通过以下两种方式实现:
配置文件(最为常用,体现了依赖注入DI的思想)
编程方式(写的过程中向BeanFactory去注册)
ApplicationContext与BeanFactory都是接口,ApplicationContext是由BeanFactory
接口扩展而来,它增强了BeanFactory的功能。
Bean容器能够加载的对象并不一定是严格遵循JavaBeans规范的Java类,任何可实例化的类都
可以通过Spring Bean容器加载进来。通常称这些类为POJO。
要记住,BeanFactory不仅仅只具备实例化Bean的功能,它还知道所有的Bean,可以配置和管理它们。
Spring给出一些BeanFactory的实现类,其中最为常用的是XmlBeanFactory。
1、通过文件系统
Resource res = new FileSystemResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
2、通过类路径
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
3、通过ApplicationContext加载
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
BeanFactory factory = (BeanFactory) appContext;
sping-frameword-1.2.7-with-dependencies中的dist里面是spring的包
将其中的spring.jar加入工程的类路径里面,下一步是写个javaBean
package bean ;
public class HelloBean
{
public HelloBean
{
System.out.println("init!");
}
private String msg ;
//加上getter和setter方法
};
public class Demo
{
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml") ;
//配置文件放在类路径的根路径下
BeanFactory factory = new XmlBeanFactory(res) ;
//在dist文件夹里面有spring-beans的dtd文档
HelloBean bean = (HelloBean)factory.getBean("hello") ;
//根据xml配置文件中的id号去找bean,然后从这个工厂中取出bean
System.out.println(bean.getMsg());
HelloBean bean1 = (HelloBean)factory.getBean("hello") ;
System.out.println(bean==bean1); //因为配置文件中的singleton设置为true,
//故是单例模式,所以两个bean肯定一样,所以打印true
//只有ApplicationContext才能实现bean的非延迟加载功能,所以要想让bean中的
//"init!"字符串在"before getbean!"字符串之前显示的话,那么首先必须得是单例模式,
//然后还得设置lazy-init="false",才可以做到,如果singleton="false"的话,是无法
//做到非延迟加载的!可以通过下面的代码来验证,看"before getbean!"和"init!"这两个
//字符串出现的先后顺序就一目了然了。
ApplicationContext factory = new ClassPathXmlApplicationContext("bean.xml");
System.out.println("before getbean!");
HelloBean bean2 = (HelloBean)factory.getBean("hello");
}
}
配置文件bean.xml:
将<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
拷贝进去……
<beans>
//singleton属性表明容器的bean是否使用单例模式……
//默认情况下,beanFactory就是延迟加载的
<bean id="hello" class="bean.HelloBean" singleton="true"
lazy-init="false">
<property name="msg">
<value>Hello,Spring!</value>
</property>
</bean>
</beans>
//上面的配置文件将属性的值注入到bean的属性中,这就是依赖注入的一个例子
//同时将那个javaBean注册到容器中
通常可以通过三种方式装配Bean
通过setter方法
通过构造函数
自动装配
其中,使用setter方法装配Bean是最为常用的。
如下代码的执行结果是什么?
FirstBean bean = (FirstBean)factory.getBean("my");
FirstBean bean1 = (FirstBean)factory.getBean("my");
System.out.println(bean==bean1);
结果依赖于bean元素的singleton属性,如果设置true,则以单例模式加载bean,
则永远指向同一个bean;反之则每次实例化一个。
也即在单例模式下,BeanFactory维护所有的bean
如果想让一个单例模式的bean被清理掉的话,不能简单的将bean置为null,而是必须使用
destroySingletons方法
还有一个destroyBean(String beanName,Object bean)
这两个方法都可以来垃圾回收单例模式中的bean
--------------------------------------------------------------
延迟加载:
如下代码执行的结果是什么?
System.out.println("before loading");
FirstBean bean = (FirstBean)factory.getBean("my");
System.out.println(“after loading”);
在bean的构造函数中,包含:
System.out.println(“bean init”);
结果依赖于bean的lazy-init属性,如果设置为true,则在第一次加载该bean时初始化;
否则在初始化容器时就加载所有bean。
延迟加载仅在bean单例模式下起作用。
-------------------------------------------------------------------------
初始化和清理:
Spring的初始化肯定是在依赖注入(属性设置)全部完成后才去做的。
框架提供的初始化方法肯定是先于我们自己定义的初始化方法的!比如,如果继承了
InitializingBean的话,会有一个这个接口提供的初始化方法,叫做afterPropertySet,
它的执行就是先于你定义的初始化方法的……
同理,DisposableBean接口中也定义了一个清理的方法,这个方法肯定也是先于你定义的
清理方法的!
建议使用你自己定义的初始化和清理方法,不要使用容器提供的,这样可以避免bean被污染!!!
在许多情况下,需要在对象加载后立即初始化资源,而在删除对象前先清理资源
在spring中,提供了两种方式实现初始化和清理工作。
通过设置bean的init-method和destroy-method指定初始与清理方法
通过实现InitializingBean及DisposableBean接口,由容器在加载与删除bean时自动调用。
//既然定义了一个init方法,所以可以在javaBean中设置下面的初始化方法:
public void init()
{
}
//同样销毁方法也可以类似的定义:
public void destroy()
{
}
//特别注意,如果你想运行上面自定义的destroy方法的话,你必须首先执行
factory.destroySingletons();
//否则不会去执行你上面自定义的destroy方法的!
原型bean在创建之后就脱离了factory的管理,所以呢,对于原型bean,只能初始化,而
不可以清理
<bean id="first" class="mybeans.FirstBean" init-method="init"
destroy-method="destroy" >
<property name="message">
<value>Hi, Rod Johnson</value>
</property>
</bean>
可以通过destroySingletons方法删除所有单例bean
原型bean在创建后即脱离BeanFactory的维护,所以只能调用初始化方法,而不能做清理工作。
===========================================================================
下午课程开始:
public class HelloBean implements BeanNameAware, BeanFactoryAware
{
private BeanFactory factory ;
private String name ;
public void setBeanName(String a)//由BeanNameAware继承来
{
this.name = a ;
}
//由BeanFactoryAware继承而来。
public void setBeanFactory(BeanFactory factory)
throws BeanException
{
this.factory = factory
}
}
-------------------------------------------------------
下面说说编程式加载Bean方式:
XmlBeanFactory提供两种编程方式加载Bean:
registerSingleton和registerBeanDefinition,前者不参与bean生命周期
后者参与bean的生命周期。
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
factory.registerSingleton("bb",new HelloBean());
HelloBean bean = (HelloBean)factory.getBean("bb");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
如果使用BeanDefinition的话
public static void main(String[] args)
{
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
//上面这句话告诉Spring自定义的方法名字叫做init,如果不写的话,自定义的
//初始化方法不会执行的。
/*
RootBeanDefinition rbd1 = new RootBeanDefinition(Integer.class);
ContructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbd1.setConstructorArgumentValues(cav);
factory.registerBeanDefinition("aa",rbd1);
System.out.println(factory.getBean("aa"));
*/
factory.registerBeanDefinition("aa",rbd);
HelloBean bean = (HelloBean)factory.getBean("aa");
System.out.println(bean.getMsg());
factory.destroySingletons();
}
老师的关键代码如下:
XmlBeanFactory factory = new XmlBeanFactory(res);
RootBeanDefinition rbd = new RootBeanDefinition();
rbd.setBeanClass(HelloBean.class);
rbd.setInitMethodName("init");
RootBeanDefinition rbdi = new RootBeanDefinition(Integer.class);
ConstructorArgumentValues cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue("12");
rbdi.setConstructorArgumentValues(cav);
=====================================================================
bean里面的属性是各式各样的,我们上面使用的实体类只是使用了String类型,根本没有考虑
其他的类型
bean装配方式:
通过Setter方法、通过构造函数、自动装配三种方法都可以达到装配Bean的目的。
其中使用setter方法装配Bean是最为常用的。
先说一下setter方法的装配:
setter方法可以装配基本类型、Bean类型、内部bean类型、集合类型、设置空值
所谓Bean类型属性是指这个属性类型是个javaBean,并且这个javaBean必须已经在Spring
中注册过了!
对于基本数据类型,
可以包括八种基本类型以及其包装类
<property name="" value="" />就可以了,不用在意具体类型,Spring会自动转换的。
装配基本类型:
包括八种基本类型及它们的包装类,还有String类型。
不必关心具体类型,spring可以通过反射机制了解到属性的类型信息
可以通过<property>的子元素<value>来设置基本类型的值,也可以通过其属性value来设置,
效果完全相同。
<bean id="first" class="mybeans.FirstBean" >
<property name="message">
<value>Hi, Rod Johnson</value>
</property>
<property name="age" value="1" />
//注意不能同时使用value子元素和value属性
</bean>
--------------------------------------------------------------------------
装配bean类型属性:
只有通过配置文件向容器注册的bean才能通过注入机制设置到其它bean的属性上。
使用<ref>子元素或ref属性设置
Spring即是通过这种方式建立起bean间的依赖关系,实现强大的bean管理功能。
举例说明:
BasicDataSource
引入包commons-dbcp、commons-pool以及commons-collections三个包引入
还有mysql的驱动程序
将BasicDataSource中的setter方法注入Spring中去。
在bean.xml中:
//将BasicDataSource中的setter方法中的对应值设置进去!
<beans>
<bean id="data" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///j2ee"/>
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="course" class="bean.CourseBean">
<property name="dataSource" ref="data"/>
//由于是bean,所以使用ref!
</bean>
</beans>
建立一个Bean,对应数据库中的一个表
public class CourseBean
{
private int id ;
private String name ;
private DataSource dataSource ;
//加入getter和setter方法
public void save()
{
}
}
然后就可以进行一下数据库的操作了……
在main函数中执行下面的代码:
---------------------------------------------------------------
Resource res = new ClassPathResource("bean.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
CourseBean course = (CourseBean)factory.getBean("course");
//由于数据源和courseBean之间的依赖关系已经通过配置文件给配置好了,所以这里
//只需要得到courseBean,就自然有了数据源的bean了。
course.setName("adsf");
course.save();
-----------------------------------------------------------------
所谓DAO就是既有值,又可以将这个值存入数据库的对象,也就是数据库访问对象
Data Access Object
所谓VO就是仅仅有值,也就是value object,值对象。
上面的这个course就是DAO了。
上面的save方法可以简单的写成下面的样子:
public void save()
{
try
{
Connection con = this.dataSource.getConnection();
String sql = "insert into courses (coursename,period)"+
"values(rtrim(?),rtrim(?))" ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
pstmt.setString(1,this.coursename);
pstmt.setInt(2,this.period.intValue());
pstmt.executeUpdate();
}
catch (SQLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
======================================================================
如果一个bean在使用前,其某个属性的值必须已经通过注入机制注入,spring可以协助检查这个属性
是否被初始化。
bean的属性dependency-check即用来实现这样的功能,其可选值包括
none --不检查
objects --仅检查bean类型
simple --仅检查基本类型(8种)和String类型
all --全检查
default --默认,不检查
此外,因为可能会调用其它对象的方法,有时一个对象在使用前必须要求另外一个对象已经初始化完成
这种依赖关系可以通过depends-on属性来实现,spring会保证在初始化当前对象前将depends-on
指定的对象也初始化出来。
如果依赖多个对象,使用逗号将它们的名字分开。
内部Bean
<bean id="outer" class="...">
<property name="target">
<bean class="com.mycompany.PersonImpl">
<property name="name">
<value>Tony</value>
</property>
</bean>
</property>
</bean>
----------------------------------------------------
Spring支持以下四种集合的装配:
<list>--java.util.List
<set>--java.util.Set
<map>--java.util.Map
<props>--java.util.Properties
list:
<property name="someList">
<list>
<value>someValue</value>
<ref bean="myDataSource"/>
<list>
<value>anyValue</value>
</list>
</list>
</property>
set:
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource"/>
</set>
</property>
map:
<property name="someMap">
<map>
<entry>
<key><value>yup an entry</value></key>
<value>just some string</value>
</entry>
<entry>
<key><value>yup a ref</value></key>
<ref bean="myDataSource"/>
</entry>
</map>
</property>
props:
<property name="people">
<props>
<prop key="HarryPotter">
The magic property
</prop>
<prop key="JerrySeinfeld">
The funny property
</prop>
</props>
</property>
==========================================================
==========================================================
如果属性没有setter方法的话,需要考虑使用构造方法装配pbean的属性,这就是
构造装配
一般在以下情况使用:
属性没有setter方法,是只读属性
属性只需要设置一次,以后就不会再更改
一般使用构造装配只装配少量属性
注意在构造装配下,构造函数中应该包含有需要装配的属性
比如:
<bean id="i" class="java.lang.Integer">
<constructor-arg value="23" />
</bean>
这就是利用构造函数将Integer注入到容器中去。
Integer i = (Integer)factory.getBean("i");
System.out.println(i);
-----------------------------------------------------
<bean id="first" class="mybeans.FirstBean">
<constructor-arg>
<value>http://www.sohu.com</value>
</constructor-arg>
<constructor-arg>
<value>http://localhost:8080</value>
</constructor-arg>
<property name="age" value="1" />
</bean>
多个参数时使用多个constructor-arg指定,出现次序决定了参数次序,或者使用index属性指定
======================================================
自动装配:
可以通过spring框架自动为bean装配属性。
自动装配只能装配bean类型,即取代ref元素。
使用自动装配只需在bean元素中加入属性autowire,自动装配可被手动装配覆盖。
也可以选择在beans中加入default-autowire属性,为所有bean设置默认自动装配。
“no“-不使用自动装配,spring推荐。
“byName”-依据名称或ID装配bean,如果没有找到,则不装配,可依赖dependency-check
属性检查是否装配。
“byType”-依据类型自动装配,如果存在两个以上同种类型,则抛出异常。
“constructor”-依据当前bean构造函数装配,查找与构造函数参数同类型bean
“autodetect”-自动检测,先通过constructor,再使用byType
Spring是不推荐使用自动装配的,首先是系统开销的问题,还有就是同名的设置可能会导致
意外的问题……
====================================================================
通过BeanFactory获取Bean与直接new一个Bean是完全不同的。
不相同的地方在于:从factory中得到的bean是被注入依赖关系的bean,而new出来的bean
则没有依赖关系,属性是空的。
通过BeanFactory获取的bean能将所有依赖注入到bean中,属性的值会依设置而定。
New出来的bean属性值必须主动设置。
在需要使用spring框架情况下,所有bean都应该由容器来管理。
===================================================================
单例和原型的问题:依赖于singleton参数,true为单例模式。
延迟加载:体现在整个容器初始化的时候立刻加载bean还是等到使用这个bean的时候才加载。
factory.getBean的时候就已经是开始使用bean了,并不一定要访问其中的属性
才算是使用。
只有ApplicationContext才能做到容器初始化的时候立刻加载bean,BeanFactory
是做不到的。
注册bean的时候,name属性是用的别名,id属性标明真名。name一般是在web开发里面去用,name
里面是可以包含一些特殊符号的,用于告诉开发者当前的属性代表什么具体的实际意思。
setter方法、构造函数和自动装配三种装配bean的方式
=====================================================================
ApplicationContext:
ApplicationContext与BeanFactory的作用相类似,都起到装配、管理Bean的作用。
不同的是,ApplicationContext在此基础上增强了BeanFactory的功能,这包括国际化、
加载资源、发布事件等等。
国际化的支持:
Spring提供了两个实现了MessageSource接口的类,它们都在
org.springframework.context.support包中:
ResourceBundleMessageSource使用JFC中标准的java.util.ResourceBundle来操作资源
ReloadableResourceBundleMessageSource 可以在不重启虚拟机的情况下重新加载资源。
ResourceBundleMessageSource是具体的类而且有setter方法,所以可以注入
根据setBasename,
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="bean.res" />
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
这里还需要在bean包下面建立一个资源包res.properties,
在里面写上:
msg=Hello,{0}
public static void main(String[] args)
{
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
String s = context.getMessage("msg",new Object[]{"Spring-Hibernate"},new Locale("zh"));
System.out.println(s);
}
这就打印出了“Hello,Spring-Hibernate”
--------------------------------------------------------
假如有多个资源包呢?
比如我又在bean包里面建了一个ress.properties
m=M
那么
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>bean.res</value>
<value>bean.ress</value>
</list>
</property>
</bean>
--------------------------------------------------------
可以通过IOC机制加载资源,如
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<value>springResource</value>
</property>
</bean>
或者
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
千万注意一点,只要是资源包的话,id必须起名字为“messageSource”!!!!
相关推荐
在Spring Boot框架中,Bean装配是核心...在component-demo这个示例中,可能会包含一个或多个演示如何装配Bean的代码片段,例如自定义配置类、Bean注入等。通过学习和实践,我们可以加深对Spring Boot Bean装配的理解。
本文将深入探讨Spring装配Bean的实例代码,帮助你更好地理解这一关键概念。 首先,Spring装配Bean主要有两种方式:XML配置和注解配置。在本例中,我们将重点关注XML配置,对应的压缩包文件名为“springxmldemo”,...
Spring装配Bean的3种方式总结 Spring框架是Java EE应用程序的核心框架之一,它提供了依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)等功能。依赖注入是Spring框架的核心...
Spring容器负责初始化、装配以及管理这些Bean。Bean的装置(配置)可以通过XML、Java配置类或者注解实现。这里提到的jar包可能包含了Spring框架的核心库,用于支持Bean的配置和管理。 XML配置是最传统的Spring Bean...
以上就是Spring使用注解方式装配Bean的基本过程和关键注解的介绍。通过这种方式,我们可以轻松地管理Bean的生命周期,实现依赖注入,以及对Bean的其他配置,极大地提高了代码的可维护性和灵活性。在实际项目中,结合...
在本文中,我们将深入探讨Spring框架中的Bean XML配置,这是Spring的核心特性之一,它允许我们定义、管理和装配应用中的对象。我们将围绕以下知识点展开: 1. **Spring框架基础**: Spring是一个开源的Java平台,...
6. Spring Bean 的装配 - 自动装配:通过`@Autowired`注解自动寻找匹配类型的Bean进行装配。 - 配置文件指定:在XML配置文件中使用`<bean>`标签的`ref`属性指定依赖的Bean。 - 使用`@Qualifier`:当有多个相同...
本文将深入探讨Spring装配基本属性的原理,帮助你更好地理解如何在代码中使用和配置这些属性。 首先,Spring装配的基本方式有两种:XML装配和基于注解的装配。XML装配是早期版本Spring的主要装配方式,通过`<bean>`...
在Spring中,Bean通常代表应用程序中的一个对象,这些对象由Spring容器(ApplicationContext)管理,包括创建、初始化、装配和销毁。Bean可以通过XML配置文件、注解或者Java配置类进行定义。 1. **Bean的定义**:在...
Spring装配bean方法实例总结 Spring框架中,bean的装配是非常重要的一个步骤,它可以通过多种方式来实现,包括XML配置、Java配置和自动装配等。下面是Spring装配bean方法实例总结。 一、XML配置 在Spring框架中...
在Spring中,Bean是应用中的对象,它们由Spring IoC容器负责创建、管理和装配。Bean配置是定义这些对象如何被创建和如何相互关联的过程。 **IoC(Inversion of Control)和DI(Dependency Injection)**: IoC是...
2. **@Autowired注解的误用**:Spring的自动装配机制可能导致Bean的多次实例化。如果一个BeanA依赖于另一个BeanB,同时BeanB也依赖于BeanA,那么Spring在处理依赖关系时可能会陷入循环引用,导致两个Bean都实例化两...
- **Bean容器**:管理对象的生命周期和装配,提供对象间协作的能力。 - **Spring MVC**:用于构建Web应用程序,提供模型-视图-控制器架构。 2. **Spring6的新特性** - **Java 17支持**:Spring6将全面支持Java ...
6. **Spring的自动装配(autowiring)**:Spring可以自动识别并装配Bean的依赖,减少了显式配置的工作量,有byType、byName等多种方式。 7. **集合装配**:Spring支持对数组、List和Map类型的属性进行装配,使得...
### Spring Bean 属性详解 Spring框架是Java平台上的一个开源框架,主要用来简化企业级应用程序的开发。在Spring中,核心概念之一就是Bean,它是一个简单的Java对象,由Spring IoC容器管理。Spring通过XML配置文件...
8. 使用Bean:在这个阶段,Bean已经实例化,并且已经可以使用。 9. 销毁:在这个阶段,Bean已经实例化,并且已经销毁。 在整个生命周期中,Spring提供了多种方式来实现Bean的初始化,例如使用init-method参数、...
- **`byName`**:根据属性名称进行自动装配,Spring会尝试将名称匹配的Bean注入到相应的位置。 - **`byType`**:根据类型进行自动装配,如果BeanFactory中有且只有一个Bean与属性类型匹配,则自动装配该属性。如果...
Spring Bean 是 Spring 框架的核心概念,它代表了应用程序中的一个对象,这个对象可以被 Spring 容器管理,包括创建、初始化、装配、销毁等生命周期过程。在 Spring 中,Bean 定义是由 `BeanDefinition` 接口来表示...
因此,我们无法直接引用该博客内容,不过我们可以基于Spring装配的一般知识进行深入讨论。 ### Spring装配的基本概念 1. **Bean**: 在Spring中,一个Java对象被称为一个Bean。Spring容器负责创建、初始化、配置以及...
Spring的核心在于其BeanFactory和ApplicationContext,它们使得对象的管理和装配变得简单。这里我们将详细探讨如何在Java中通过Spring获取配置的bean。 1. **BeanFactory与ApplicationContext** - **BeanFactory*...