Spring学习笔记(1)
1. Spring开发步骤1.1建立Java或JavaEE项目1.2导入相关的jar包
org.springframework.asm-3.1.1.RELEASE.jar--字字码处理
org.springframework.core-3.1.1.RELEASE.jar--spring核心,访问资源
org.springframework.beans-3.1.1.RELEASE.jar--核心容器
org.springframework.context-3.1.1.RELEASE.jarApplicationContext等类在这个包中
org.springframework.expression-3.1.1.RELEASE.jarSpring3 EL
commons-logging.jar---spring所必须依赖的唯一第三方,日志
1.3创建测试类Peron类:
publicclass Person {
private Integerid;
private Stringname;
private Integerage;
private Addressaddress;
}
Address类:
publicclassAddress {
private Stringprovince;
private Stringcity;
private Stringarea;
}
配置文件beans.xml:
<?xmlversion="1.0"encoding="UTF-8"?>
<!-- 文档申明,spring3的配置文件使用schema来约束 -->
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="address"class="com.maple.spring.helloworld.Address">
<propertyname="province"value="广东省"/>
<propertyname="city"value="广州市"/>
<propertyname="area"value="海珠区"/>
</bean>
<!-- 默认使用空参构造器创建对象 -->
<bean id="p"name="p1"class="com.maple.spring.helloworld.Person">
<propertyname="id"value="1000"/>
<propertyname="name"value="张三"/>
<propertyname="age"value="23"/>
<!-- 引用另外一个bean -->
<propertyname="address"ref="address"/>
</bean>
<!-- 给p取别名 -->
<alias name="p"alias="p11"/>
<!-- 使用有参构造器创建对象 -->
<bean id="p2"class="com.maple.spring.helloworld.Person">
<!-- 顺序最好和构造器中的参数顺序保持一致 -->
<constructor-argvalue="1000"/>
<constructor-argvalue="张三"/>
<constructor-argvalue="23"/>
<constructor-argref="address"/>
</bean>
</beans>
2.Spring容器详解2.1容器概述功能多样式:不仅提供放东西的功能;还承担容器中对象的创建,负责相互关系管理等功能;周边性的功能(日志、安全检查)。
Java中容器的发展:无容器(JVM+程序员)=工厂时代--->旧EJB时代,重量级容器(JavaEE容器,对放到容器中有非常多限制)/或者某一种领域(Web容器)-->轻容器时代(PicoContainer、Spring、Apache HiveMind、Guice、xWork)--新EJB时代(对放进容器中没有太多限制)
2.2控制反转(Inversion of Control ,IOC)概念:一个组件所依赖的对象,是由外部(容器)负责创建并设置到组件里面。把依赖的对象控制权从组件内部转移到外部(容器),就称控制反转IOC,其核心是依赖注入。
public class Girl {
private Boy boy = new Boy();//Girl所依赖的对象
public void kiss() {
System.out.println(boy.getBoyObject());
}
}
boy是在应用内部创建及维护的。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转,目的是为了获得更好的扩展性和良好的可维护性。
2.3依赖注入(Dependency Injection)所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。
依赖注入:给一个组件注入其所依赖的对象,具体的方式有四种。
A接口注入Type1(过时)/Type2
B设值方法注入(setter)/Type3
C构造子注入
D字段注入(Field注入)
1) 使用setter注入:
2) 使用构造子注入:
3) 使用字段注入:
publicstaticvoid main(String[]args) {
ApplicationContextacx = new ClassPathXmlApplicationContext("com/maple/spring/inject/beans.xml");
// Personp1 = (Person) acx.getBean("p1");//setter
// p1.say();
// Personp2 = (Person) acx.getBean("p2");//构造子
// p2.say();
Personp3 = (Person) acx.getBean("p3");//字段
p3.say();
}
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 使用setter方式注入 ,被注入值的属性要提供setter方法-->
<bean id="p1"class="com.maple.spring.inject.Person">
<propertyname="id"value="1000"/>
<propertyname="name"value="张三"/>
<propertyname="age"value="22"/>
</bean>
<!-- 使用有参构造器创建对象 -->
<bean id="p2"class="com.maple.spring.inject.Person">
<!-- 顺序最好和构造器中的参数顺序保持一致通过index及type来明确的指定参数位置及类型-->
<constructor-argvalue="2000"/>
<constructor-argvalue="李四"/>
<constructor-argvalue="23"/>
</bean>
<!-- 使用字段注入 -->
<bean id="p3"class="com.maple.spring.inject.Person">
<propertyname="id"value="1000"/>
<propertyname="name"value="张三"/>
</bean>
<!-- 起动注解扫描功能,字段注入要用到-->
<context:annotation-config/>
<!-- 使用字段注入时,除了要在字段上加@Autowired标签外,还要提供一个匹配类型的bean。用于自动设置到字段上 -->
<bean id="age1"class="java.lang.Integer">
<constructor-argvalue="24"/>
</bean>
</beans>
3.Spring容器初始化过程(不同的实现有不同的过程)A、根据加载到的配置文件信息注册Bean的信息(BeanDefinition)到Bean工厂。
B、根据得到BeanDefinition对象来确实是否要初始化一些Bean。
C、处理依赖注入(根据BeanDefinition中有关依赖注入的信息)
D、客户端通过容器来查询业务组件。
E、当容器关闭的时候,销毁。
4.Bean工厂及应用上下文1)BeanFactory--Spring最基本容器接口
2)ApplicationContext--应用层面容器(提供访问环境资源信息的相关方法)
ApplicationContext getParent()--容器层结构的概念
ApplicationContext会在初始化的自动加载单例Bean。而BeanFactory在初始化的时候不会加载。
应用上下文ApplicationContext是建立在BeanFactory基础上的一种更高层次的Spring IOC容器,其除了具有普通BeanFactory的全部功能以外,还加入了资源访问、事件传播及自动载入上下文等跟应用程序紧密相关的功能。
在J2EE应用程序中,大多数时候都直接使用应用上下文件ApplicationContext,比如Web应用等,而且一般不会在程序中使用代码来加载应用程序上下文,而是采用声明的方式,在应用程序启动的过程中自动加载应用程序上下文。
5.三种实例化Bean的方式5.1通过构造函数默认无参构造函数,也可以使用带参数的。
(1)无参数的构造函数
publicPerson() {
System.out.println("初始化person");
}
(2) 无参数的配置
<!-- 使用默认的无参数构造函数来初始 -->
<beanid="p1"class="cn.itcasg.gz.springioc.Person"></bean>
(3)带参数的构造函数
public Person(String name) {
this.name= name;
System.out.println("创建Person,构造函数1");
}
(4)带参数的配置
<!--指定使用带一个参数的构造函数来初始化Bean -->
<beanid="p2" class="cn.itcasg.gz.springioc.Person">
<constructor-argvalue="张无忌"></constructor-arg>
</bean>
5.2使用静态工厂方法(1)无参的工厂类
public class PersonFactory {
publicstatic Person createPerson(){
System.out.println("createPerson()...");
return new Person();
}
}
(2) 无参的配置
<!-- 使用静态工厂方法创建Person-->
<bean id="p3"class="cn.itcasg.gz.springioc.PersonFactory"factory-method="createPerson"></bean>
(3)带参数的工厂方法
public class PersonFactory {
publicstatic Person createPerson(String name){
System.out.println("createPerson()...222222");
returnnew Person(name);
}
}
(4) 带参数的配置
<!--使用带参数的静态工厂方法-->
<beanid="p4" class="cn.itcasg.gz.springioc.PersonFactory"factory-method="createPerson">
<constructor-argvalue="杨过"></constructor-arg>
</bean>
5.3使用动态工厂方法(1)工厂类
public class PersonFactoryFamily {
privateString family;
publicvoid setFamily(String family) {
this.family= family;
}
public Person createPerson(){
System.out.println("createPerson()...");
returnnew Person(family+":");
}
public Person createPerson(String name){
System.out.println("createPerson()...2");
returnnew Person(family+":"+name);
}
}
(2)配置
<!-- 使用动态工厂方法创建Person -->
<!--先定义工厂Beanclass的值为工厂类的全类名-->
<beanid="wangFactory" class="cn.itcasg.gz.springioc.PersonFactoryFamily">
<propertyname="family" value="王"/>
</bean>
<beanid="p5" factory-bean="wangFactory"(指明使用哪个工厂类)
factory-method="createPerson"(指明调用工厂类的哪个方法)>
<constructor-argvalue="小二"/> </bean>
<beanid="p6" factory-bean="wangFactory" factory-method="createPerson"/>
6. Bean的作用域(存活期)1)singleton(默认值)
在每个Spring IoC容器中一个bean定义只有一个对象实例(共享)。
默认情况下会在容器启动时初始化bean,但我们可以指定Bean节点的lazy-init=“true”来延迟初始化bean,这时候,只有第一次获取bean会才初始化bean。如:
<bean id="xxx"class="cn.itcast.OrderServiceBean" lazy-init="true"/>
如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true“,如下:
<beans default-lazy-init="true“...>
2)prototype 允许bean可以被多次实例化(使用一次就创建一个实例)
3)request生存期在一次请求内有效。必寻在WEB引用中才能用。和web中的request对象的生存期一样。
4)session生存期在一次会话内有效。在web应用中才有效。(如购车Bean)
5)global session(Portlet规范将portlet定义为一种“基于Java技术的web组件,由处理请求和生成动态内容的portlet容器管理”) Portlet环境应用中才有效。
7.装配的方式7.1手动装配以下三种都是手动装配:参见2.3
使用到的标签或注解<property>、<constructor-arg>、@Autowired、@Resource。
1) 使用setter注入:
2) 使用构造子注入:
3) 使用字段注入:
7.2自动装配(少用)autowire属性来指定自动装配的类型。
<bean id="p4"class="com.maple.spring.inject.Person" autowire="byName"/>
autowired属性的取值:
byName:按名称自动装配,不会装配基本类型。
byType:按类型自动装配
constructor:会按照构造函数参数的类型来自动装配.会选择参数最多的一个来,依次查询参数个数少的。