Spring 2.5 ( 传智播客) ----笔记
2011-02-11 13:55
197 查看
Spring 2.5
1)
www.springframework.org
dist/spring.jar
lib/jakarta-commons/commons-logging.jar
lib/aspectj/aspectjweaver.jar和aspectjrt.jar
lib/cglib/cglib-nodep-2.1_3.jar
lib/j2ee/common-annotations.jar
2)
在类路径下寻找配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
在文件系统路径下寻找
ApplicationContext ctx=new FileSystemXmlApplicationContext(new String[]{"d://beans.xml"});
可以指定多个配置文件,通过String数组传入
3)
<bean id=“orderService" class="cn.itcast.OrderServiceBean"/>
使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
4)Bean的作用域
singleton
prototype
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean" scope="prototype"></bean>
5)bean的生命周期
默认在容器实例化时即实例化
如果是prototype则是在获取的时候才实例化
lazy-init="true"
或<beans ... default-lazy-init="true" >则所有的bean都默认在容器启动时即实例化
init-method=""
destroy-method="destroy"
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
ctx.close();
正常关闭时会得到调用
6)
由于spring的schema文件位于网络上,如果机器不能连接到网络,那么在编写配置信息时候就无法出现提示信息,解决方法有两种:
1。让机器上网,eclipse会自动从网络上下载schema文件并缓存在硬盘上。
2。手动添加schema文件,方法如下:
windwos->preferences->myeclipse->files and editors->xml->xmlcatalog
点"add",在出现的窗口中的Key Type中选择URI,在location中选"File system",
然后在spring解压目录的dist/resources目录中选择spring-beans-2.5.xsd,
回到设置窗口的时候不要急着关闭窗口,应把窗口中的Key Type改为Schema location,
Key改为http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
7)
<bean id="personDao" class="cn.itcast.impl.PersonDaoBean" ></bean>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="name" value="aa"/>
<property name="personDao" ref="personDao" > </property>
</bean>
8) spring注入原理模拟
(1) class ProperrtyDefiniton有三个属性
private String name
private String ref
private String value
(2)读取applicationContext.xml时的关键代码
XPath propertysub=element.createXPath("ns:property");
propertysub.setNamespaceURIs(nsMap);
List<Element> propertys=propertysub.selectNodes(element);
for(Element property:propertys){
String propertyName=property.attributeValue("name");
String propertyref=property.attributeValue("ref");
String propertyValue=property.attributeValue("value");
PropertyDefinition propertyDefinition=new PropertyDefinition(propertyName,propertyref,propertyValue);
beanDefine.getPropertys().add(propertyDefinition);
}
(3)注入的关键代码
//beanDefinition 存放applicationContext.xml中的一个<bean>节点,这个节点下可能有多个<property>节点
//Object bean=sigletons.get(beanDefinition.getId());
//sigletons中存放整个applicationContext.xml中的<beans>节点
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getclass()).getPropertyDescriptors();
for(PropertyDefiniton propertyDefinition:beanDefinition.getPropertys()){//循环从xml文件的bean节点获取的<property>节点
for(PropertyDescriptor properdesc:ps){ //循环从class文件中得到属性信息
if(propertyDefinition.getName().equals(properdesc.getName())){
Method setter=properdesc.getWriteMethod();
if(setter!=null){
object value=null;
if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())){
value=sigletons.get(propertyDefinition.getRef());
}
else{ //参见commons-beanutils-1.8.0.jar
value=ConvertUtils.convert(propertyDefinitoin.getValue().properdesc.getPropertyType());
}
setter.setAccessible(true);
setter.invoke(bean,value);
}
break;
}
}
}
(4)
apache-commons/commons-beanutils-1.8.0.jar
9)各种依赖注入方式
<bean id="personService class="cn.itcast.service.impl.PersonServiceBean">
<property name="psesonDao">
<bean class="cn.itcast.dao.impl.PersonDaoBean"/>
</property>
<property name="name" value="itcast" /> <!-- String -->
<property name="id" value="88" /> <!-- Integer -->
<property name="lists">
<list>
<value>lihuoming</value>
</list>
</property>
<property name="sets">
<set>
<value>set</value>
</set>
</property>
<property name="maps">
<map>
<entry key="lihuoming" value="28"/>
</map>
</property>
<property name="properties">
<props>
<prop key="12">sss</prop>
</props>
</property>
</bean>
private Set<String> sets = new HashSet<String>();
private List<String> lists = new ArrayList<String>();
private Properties properties = new Properties();
private Map<String, String> maps = new HashMap<String, String>();
10)使用构造器注入
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean">
<constructor-arg index="0" type="cn.itcast.dao.PersonDao" ref="personDao"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="传智播客" ></constructor-arg>
11)使用@Resource注解完成属性装配
要更改 xml文件的头部信息
额外缩进的行是新增的
<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">
<context:annotation-config/>
</beans>
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
@Resource注解在spring安装目录的lib/j2ee/common-annotations.jar
@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Autowired
private PersonDao personDao;//用于字段上
@Autowired
public void setOrderDao(OrderDao orderDao) {//用于属性的setter方法上
this.orderDao = orderDao;
}
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,
可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier("personDaoBean")
private PersonDao personDao;
@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。
名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,
即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,
即默认取属性名作为bean名称寻找依赖对象。
@Resource(name=“personDaoBean”)
private PersonDao personDao;//用于字段上
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。
但一旦指定了name属性,就只能按名称装配了。
可以不加入get,set方法,非常简洁
12)注释的原理
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface ItcastResource{
public String name() default "";
}
private void annotationInject(){
for(String beanName:sigletons.keySet()){
Object bean=sigletons.get(beanName);
if(bean!=null){
try{
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor properdesc:ps){
Method setter=properdesc.getWriteMethod();
if(setter!=null&&setter.isAnnotationPresent(ItcastResource.class)){
ItcastResource resource=setter.getAnnotation(ItcastResource.class);
Object value=null;
if(resource.name()!=null&&!"".equals(resource.name())){
value=sigletons.get(resource.name());
}
else{
value=sigletons.get(properdesc.getName());//这行有点问题,实参应该是setter的形参的变量名,
//或许应该是setter.getTypeParameters()
if(value==null){
for(String key:sigletons.keySet()){
if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){
value=sigletons.get(key);
break;
}
}
}
}
setter.setAccessible(true);
setter.invoke(bean,value);
}
}
Field[] fields=bean.getClass().getDeclaredFields();
for(Field field:fields){
if(field.isAnnotationPresent(ItcastResource.class)){
ItcastResource resource=field.getAnnotation(ItcastResource.class);
Object value=null;
if(resource.name()!=null&&!"".equals(resource.name())){
value=sigletons.get(resource.name());
}
else{
value=sigletons.get(field.getName());
if(value==null){
for(String key:sigletons.keySet()){
if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){
value=sigletons.get(key);
break;
}
}
}
}
field.setAccessible(true);
field.set(bean,value);
}
}
}catch(IntrospectionException e){
e.printStackTrace();
}
}
}
}
13)让Spring自动扫描和管理Bean
前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,
通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,
查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了
@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。
它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息
通过在classpath自动扫描方式把组件纳入spring 容器中管理
<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">
<context:component-scan base-package="cn.itcast"/>
</beans>
其中base-package为需要扫描的包(含子包)。
@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action)、
@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,
当组件不好归类的时候,我们可以使用这个注解进行标注。
来自于org.springframework.stereotype.Repository等
bean的名称是类的简单名称并且把首字母小写
或者
在类的定义前加上
@Service("personService")
@Scope("prototype") //org.springframework.context.annotation.Scope
@PostConstruct
<context:component-scan base-package="cn.itcast"/>这一行包括了很多处理器
其中有 <context:annotation-config/>
@PreDestroy
1)
www.springframework.org
dist/spring.jar
lib/jakarta-commons/commons-logging.jar
lib/aspectj/aspectjweaver.jar和aspectjrt.jar
lib/cglib/cglib-nodep-2.1_3.jar
lib/j2ee/common-annotations.jar
2)
在类路径下寻找配置文件
ApplicationContext ctx=new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
在文件系统路径下寻找
ApplicationContext ctx=new FileSystemXmlApplicationContext(new String[]{"d://beans.xml"});
可以指定多个配置文件,通过String数组传入
3)
<bean id=“orderService" class="cn.itcast.OrderServiceBean"/>
使用静态工厂方法实例化
<bean id="personService" class="cn.itcast.service.OrderFactory" factory-method="createOrder"/>
public class OrderFactory {
public static OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
使用实例工厂方法实例化:
<bean id="personServiceFactory" class="cn.itcast.service.OrderFactory"/>
<bean id="personService" factory-bean="personServiceFactory" factory-method="createOrder"/>
public class OrderFactory {
public OrderServiceBean createOrder(){
return new OrderServiceBean();
}
}
4)Bean的作用域
singleton
prototype
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean" scope="prototype"></bean>
5)bean的生命周期
默认在容器实例化时即实例化
如果是prototype则是在获取的时候才实例化
lazy-init="true"
或<beans ... default-lazy-init="true" >则所有的bean都默认在容器启动时即实例化
init-method=""
destroy-method="destroy"
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
ctx.close();
正常关闭时会得到调用
6)
由于spring的schema文件位于网络上,如果机器不能连接到网络,那么在编写配置信息时候就无法出现提示信息,解决方法有两种:
1。让机器上网,eclipse会自动从网络上下载schema文件并缓存在硬盘上。
2。手动添加schema文件,方法如下:
windwos->preferences->myeclipse->files and editors->xml->xmlcatalog
点"add",在出现的窗口中的Key Type中选择URI,在location中选"File system",
然后在spring解压目录的dist/resources目录中选择spring-beans-2.5.xsd,
回到设置窗口的时候不要急着关闭窗口,应把窗口中的Key Type改为Schema location,
Key改为http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
7)
<bean id="personDao" class="cn.itcast.impl.PersonDaoBean" ></bean>
<bean id="orderService" class="cn.itcast.service.OrderServiceBean">
<property name="name" value="aa"/>
<property name="personDao" ref="personDao" > </property>
</bean>
8) spring注入原理模拟
(1) class ProperrtyDefiniton有三个属性
private String name
private String ref
private String value
(2)读取applicationContext.xml时的关键代码
XPath propertysub=element.createXPath("ns:property");
propertysub.setNamespaceURIs(nsMap);
List<Element> propertys=propertysub.selectNodes(element);
for(Element property:propertys){
String propertyName=property.attributeValue("name");
String propertyref=property.attributeValue("ref");
String propertyValue=property.attributeValue("value");
PropertyDefinition propertyDefinition=new PropertyDefinition(propertyName,propertyref,propertyValue);
beanDefine.getPropertys().add(propertyDefinition);
}
(3)注入的关键代码
//beanDefinition 存放applicationContext.xml中的一个<bean>节点,这个节点下可能有多个<property>节点
//Object bean=sigletons.get(beanDefinition.getId());
//sigletons中存放整个applicationContext.xml中的<beans>节点
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getclass()).getPropertyDescriptors();
for(PropertyDefiniton propertyDefinition:beanDefinition.getPropertys()){//循环从xml文件的bean节点获取的<property>节点
for(PropertyDescriptor properdesc:ps){ //循环从class文件中得到属性信息
if(propertyDefinition.getName().equals(properdesc.getName())){
Method setter=properdesc.getWriteMethod();
if(setter!=null){
object value=null;
if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())){
value=sigletons.get(propertyDefinition.getRef());
}
else{ //参见commons-beanutils-1.8.0.jar
value=ConvertUtils.convert(propertyDefinitoin.getValue().properdesc.getPropertyType());
}
setter.setAccessible(true);
setter.invoke(bean,value);
}
break;
}
}
}
(4)
apache-commons/commons-beanutils-1.8.0.jar
9)各种依赖注入方式
<bean id="personService class="cn.itcast.service.impl.PersonServiceBean">
<property name="psesonDao">
<bean class="cn.itcast.dao.impl.PersonDaoBean"/>
</property>
<property name="name" value="itcast" /> <!-- String -->
<property name="id" value="88" /> <!-- Integer -->
<property name="lists">
<list>
<value>lihuoming</value>
</list>
</property>
<property name="sets">
<set>
<value>set</value>
</set>
</property>
<property name="maps">
<map>
<entry key="lihuoming" value="28"/>
</map>
</property>
<property name="properties">
<props>
<prop key="12">sss</prop>
</props>
</property>
</bean>
private Set<String> sets = new HashSet<String>();
private List<String> lists = new ArrayList<String>();
private Properties properties = new Properties();
private Map<String, String> maps = new HashMap<String, String>();
10)使用构造器注入
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean">
<constructor-arg index="0" type="cn.itcast.dao.PersonDao" ref="personDao"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="传智播客" ></constructor-arg>
11)使用@Resource注解完成属性装配
要更改 xml文件的头部信息
额外缩进的行是新增的
<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">
<context:annotation-config/>
</beans>
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
@Resource注解在spring安装目录的lib/j2ee/common-annotations.jar
@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Autowired
private PersonDao personDao;//用于字段上
@Autowired
public void setOrderDao(OrderDao orderDao) {//用于属性的setter方法上
this.orderDao = orderDao;
}
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,
可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier("personDaoBean")
private PersonDao personDao;
@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。
名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,
即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,
即默认取属性名作为bean名称寻找依赖对象。
@Resource(name=“personDaoBean”)
private PersonDao personDao;//用于字段上
注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。
但一旦指定了name属性,就只能按名称装配了。
可以不加入get,set方法,非常简洁
12)注释的原理
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface ItcastResource{
public String name() default "";
}
private void annotationInject(){
for(String beanName:sigletons.keySet()){
Object bean=sigletons.get(beanName);
if(bean!=null){
try{
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor properdesc:ps){
Method setter=properdesc.getWriteMethod();
if(setter!=null&&setter.isAnnotationPresent(ItcastResource.class)){
ItcastResource resource=setter.getAnnotation(ItcastResource.class);
Object value=null;
if(resource.name()!=null&&!"".equals(resource.name())){
value=sigletons.get(resource.name());
}
else{
value=sigletons.get(properdesc.getName());//这行有点问题,实参应该是setter的形参的变量名,
//或许应该是setter.getTypeParameters()
if(value==null){
for(String key:sigletons.keySet()){
if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){
value=sigletons.get(key);
break;
}
}
}
}
setter.setAccessible(true);
setter.invoke(bean,value);
}
}
Field[] fields=bean.getClass().getDeclaredFields();
for(Field field:fields){
if(field.isAnnotationPresent(ItcastResource.class)){
ItcastResource resource=field.getAnnotation(ItcastResource.class);
Object value=null;
if(resource.name()!=null&&!"".equals(resource.name())){
value=sigletons.get(resource.name());
}
else{
value=sigletons.get(field.getName());
if(value==null){
for(String key:sigletons.keySet()){
if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){
value=sigletons.get(key);
break;
}
}
}
}
field.setAccessible(true);
field.set(bean,value);
}
}
}catch(IntrospectionException e){
e.printStackTrace();
}
}
}
}
13)让Spring自动扫描和管理Bean
前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,
通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,
查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了
@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。
它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息
通过在classpath自动扫描方式把组件纳入spring 容器中管理
<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">
<context:component-scan base-package="cn.itcast"/>
</beans>
其中base-package为需要扫描的包(含子包)。
@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action)、
@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,
当组件不好归类的时候,我们可以使用这个注解进行标注。
来自于org.springframework.stereotype.Repository等
bean的名称是类的简单名称并且把首字母小写
或者
在类的定义前加上
@Service("personService")
@Scope("prototype") //org.springframework.context.annotation.Scope
@PostConstruct
<context:component-scan base-package="cn.itcast"/>这一行包括了很多处理器
其中有 <context:annotation-config/>
@PreDestroy
相关文章推荐
- 12_传智播客Spring2.5视频教程_编码剖析@Resource注解的实现原理
- 学习笔记-----------------struts2 hibernate3 spring2.5整合
- struts2.1.8+spring2.5+hibernate3.2+ext3.0框架整合笔记
- 传智播客_传智播客spring2.5视频
- Spring2.5学习笔记
- 传智播客Spring视频教程学习笔记7
- 传智播客Spring视频教程学习笔记17 18
- 视频教程_传智播客spring2.5_avi
- Spring2.5学习笔记1-控制反转-DI容器泛型访问
- 16_传智播客Spring2.5视频教程_使用CGLIB实现AOP功能与AOP概念解释
- 重读spring2.5手册笔记
- Spring2.5注解(标注)学习笔记
- 《传智播客:2.3/spring/jdbc/EJB3.0/ajax/hibernate/Struts/java视频教程》(SPRING2.5/AJAX/JAVA/JNI/FTP/AJAX/ibatis/OA/JDBC)
- 传智播客Spring视频教程学习笔记8
- 08_传智播客Spring2.5视频教程_编码剖析Spring装配基本属性的原理
- OA学习笔记-004-Spring2.5配置
- spring2.5笔记 - 第十课 Spring整合Hiberante3
- Spring2.5学习笔记
- 传智播客-spring2.5(1)-IoC与bean的实例化、轻量级和重量级之分
- Spring2.5学习笔记1-控制反转-依赖注入类型