不明觉厉的spring(2)---spring核心容器及ioc

来源:互联网 发布:淘宝中差评外包 编辑:程序博客网 时间:2024/04/28 00:29

spring版本:3.1.0

spring包的各个作用

org.springframework.aop-3.1.1.RELEASE.jar ---- ----spring 的面向切面编程,提供AOP(面向切面编程)实现,

org.springframework.asm-3.1.1.RELEASE.jar ---- ---- Spring独立的asm程序, Spring2.5.6的时候需要asmJar 包,3.0开始提供他自己独立的asm.jar 

。ASM是小巧轻便的 Java 字节码操控框架 ,它能方便地生成和改造 Java 代码。 Hibernate 和 Spring 在底层都用到了 ASM(CgLib 底层用的 asm)。
管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。
服务、任务调度、JNDI定位、EJB 集成、远程访问、 缓存以及各种视图层框架的封装等。
件的基本核心。
已经独立成包了,现在不包含在这个包里了。这个jar文件里大部分的类都要依赖spring-dao.jar里的类,用这个包时你需要同时包含spring-dao.jar包 

特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。

org.springframework.aspects-3.1.1.RELEASE.jar ---- ---- spring整合了aspectjrt.jar,也可以使用aspectjrt.jar来代替。

org.springframework.beans-3.1.1.RELEASE.jar ---- ---- springIoC(依赖注入)的基础实现,所有应用都要用到的,它包含访问配置文件、创建和 

org.springframework.context.support-3.1.1.RELEASE.jar ---- ---- spring-context 的扩展支持,包含支持缓存Cache(ehcache)、JCA、JMX、邮 

org.springframework.context-3.1.1.RELEASE.jar ---- ----spring 提供在基础 IoC 功能上的扩展服务,此外还提供许多企业级服务的支持,如 邮件 

org.springframework.core-3.1.1.RELEASE.jar ---- ---- 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组 

org.springframework.expression-3.1.1.RELEASE.jar ---- ----spring 表达式语言。

org.springframework.instrument.tomcat-3.1.1.RELEASE.jar ---- ----spring3.1 对 Tomcat 的连接池的基成。

org.springframework.instrument-3.1.1.RELEASE.jar ---- ----spring3.1 对服务器的代理接口。

org.springframework.jdbc-3.1.1.RELEASE.jar ---- ----包含对Spring对JDBC数据访问进行封装的所有类。

org.springframework.jms-3.1.1.RELEASE.jar ---- ----提供了对JMS 1.0.2/1.1的支持类。

org.springframework.orm-3.1.1.RELEASE.jar ---- ----包含Spring对DAO特性集进行了扩展,使其支持 iBATIS、JDO、OJB、TopLink,因为Hibernate 

org.springframework.oxm-3.1.1.RELEASE.jar ---- ----spring 对Object/XMI 的映射的支持,可以让JAVA与XML之间来回切换。

org.springframework.test-3.1.1.RELEASE.jar ---- ----spring 对Junit 等测试框架的简单封装。

org.springframework.transaction-3.1.1.RELEASE.jar ---- ----为为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。

org.springframework.web.portlet-3.1.1.RELEASE.jar ---- ----springMVC 的增强,支持portlet标准(JSR168/JSR286)。

org.springframework.web.servlet-3.1.1.RELEASE.jar ---- ----对 J2EE6.0 Servlet3.0 的支持。

org.springframework.web.struts-3.1.1.RELEASE.jar ---- ---- 整合 Struts 的支持。

org.springframework.web-3.1.1.RELEASE.jar ---- ----包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext 

spring容器的实例化方式

方法一:
在类路径下寻找配置文件来实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"beans.xml"});
方法二:
在文件系统路径下寻找配置文件来实例化容器
ApplicationContext ctx = new FileSystemXmlApplicationContext(new String[]{“d:\\beans.xml“});
Spring的配置文件可以指定多个,可以通过String数组传入。

bean的实例化方法

使用构造器创建实例

无参构造函数

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean id="classA" class="spring.senssic.A"></bean></beans>
public A(){}

有参构造函数

package spring.senssic.temp;import java.util.Date;public class B {private final String name;private final int age;private final Date date;public B(String name, int age, Date date) {this.name = name;this.age = age;this.date = date;}@Overridepublic String toString() {return "实例化成功:name" + this.name + "age:" + this.age + date;}}


<?xml version="1.0" encoding="UTF-8"?><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"       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-3.1.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-3.1.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"><bean id="date" class="java.util.Date"></bean><bean id="classb" class="spring.senssic.temp.B">   <constructor-arg index="0" value="senssic"></constructor-arg>   <constructor-arg index="1" value="20"></constructor-arg>   <constructor-arg index="2" ref="date"></constructor-arg></bean></beans>
测试类:
package spring.senssic.test;import org.junit.BeforeClass;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import spring.senssic.temp.B;public class STest {private static B b;@BeforeClasspublic static void TWork() {ApplicationContext act = new ClassPathXmlApplicationContext("beans.xml");b = (B) act.getBean("classb");}@Testpublic void test() {System.out.println(b.toString());}}


使用静态工厂方法创建实例

package spring.senssic.temp;public class C {public static C createInstance() {// 必须是无参静态return new C();}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "无参静态函数";}}


bean:
<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean>

使用实例工厂方法创建实例

工厂类

package spring.senssic.temp;import java.util.Date;public class Factory {private final String name = "senssic";public B Instance() {// 必须是无参函数,且是public类型return new B(name, 20, new Date());}}

要实例化的类:
package spring.senssic.temp;import java.util.Date;public class B {private final String name;private final int age;private final Date date;public B(String name, int age, Date date) {this.name = name;this.age = age;this.date = date;}@Overridepublic String toString() {return "实例化成功:name" + this.name + "age:" + this.age + date;}}

配置:

<bean id="factory" class="spring.senssic.temp.Factory"></bean><bean id="classb" factory-bean="factory" factory-method="Instance"></bean><!--就是通过factory类来反射实例化B-->

bean的作用域

Spring Framework支持五种作用域(其中有三种只能用在基于web的Spring ApplicationContext)。 
内置支持的作用域分列如下:
作用域                                    描述


singleton---默认为此项
在每个Spring IoC容器中一个bean定义对应一个对象实例。

当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。

设置的方式

<bean id="accountService" class="spring.senssic.temp.AccountSer"/> 

<bean id="accountService" class="spring.senssic.temp.AccountSer" scope="singleton"/>  

<bean id="accountService" class="spring.senssic.temp.AccountSer" singleton="true"/> 


prototype
一个bean定义对应多个对象实例。

Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会创建一个新的bean实例 。根据经验,对有状态的bean应该使用singleton作用域,而对无状态的bean则应该使用prototype作用域。

设置方式:

<bean id="accountService" class="spring.senssic.temp.AccountSer" scope="prototype"/>  

<bean id="personService" class="spring.senssic.temp.AccountSer" scope="prototype"></bean> 


request

在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext 情形下有效。
session
在一个HTTP Session 中,一个bean定义对应一个实例。该作用域仅在基于web的SpringApplicationContext 情形下有效。
global session
在一个全局的HTTP Session 中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext 情形下有效。

其他作用域,即request、session以及global session 仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架)。这些作用域仅仅在使用基于web的Spring ApplicationContext实现(如XmlWebApplicationContext)时有用。 如果在普通的Spring IoC容器中,比如像XmlBeanFactory或ClassPathXmlApplicationContext, 尝试使用这些作用域,你将会得到一个IllegalStateException异常(未知的bean作用域)。配置只需要改下scope属性即可

bean的懒加载

在每个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“ ...>


指定Bean的初始化方法和销毁方法

指定Bean的初始化方法和销毁方法
<bean id="xxx" class="cn.itcast.OrderServiceBean" init-method="init" destroy-method="close"/>

依赖注入

spring依赖注入
使用构造器注入
使用属性setter方法注入
使用Field注入(用于注解方式)

构造函数的注入之前已经介绍

不使用注解方式

使用setter方法注入:

基本类型

java代码:属性必须有setter方法,必须有无参构造函数
package spring.senssic.temp;public class B {private String name;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private int age;public B() {}public B(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "实例化成功:name" + this.name + "age:" + this.age;}public String getName() {return name;}public int getAge() {return age;}}

配置:
<bean id="classb" class="spring.senssic.temp.B"> <property name="name" value="senssic"></property> <property name="age" value="20"></property></bean>

引用其它bean

其他定义class

package spring.senssic.temp;public class C {public static C createInstance() {// 必须是无参静态return new C();}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "无参静态函数";}}
需要配置的:

package spring.senssic.temp;public class B {private String name;private C c;public C getC() {return c;}public void setC(C c) {this.c = c;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private int age;public B() {}public B(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "实例化成功:name" + this.name + "age:" + this.age;}public String getName() {return name;}public int getAge() {return age;}}
配置文件:

<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean><bean id="classb" class="spring.senssic.temp.B"> <property name="name" value="senssic"></property> <property name="age" value="20"></property> <property name="c" ref="classc"></property></bean>

内部bean(使用内部bean,但该bean不能被其他bean使用)

引用类:
package spring.senssic.temp;class D {}
java类:
package spring.senssic.temp;public class B {public D getD() {return d;}public void setD(D d) {this.d = d;}private D d;@Overridepublic String toString() {return "lalalal";}}

配置文件:
<bean id="classb" class="spring.senssic.temp.B"> <property name="d">   <bean class="spring.senssic.temp.D"></bean> </property>

这种方式的缺点是你无法在其它地方重用这个D实例,原因是它是专门为B而用。

装配集合

若bean的属性是集合类型,按如下处理:
A、装配List和数组:
                <!-- 装配list -->
                  <propertyname="lists">
                       <list>
                        <value>list1</value>
                        <value>list2</value>
                        <refbean="person"/>
                     </list>
                   </property>
   <!--装配数组 -->
       <property name="obj">
         <list>
            <value>obj1</value>
            <value>obj2</value>
            <refbean="person"/>
         </list>
       </property>
B、 装配set:
  <!--装配set -->
       <property name="sets">
         <set>
           <value>set1</value>
           <value>set2</value>
           <refbean="person"/>
         </set>
       </property>
set使用方法和list一样,不同的是对象被装配到set中,而list是装配到List或数组中装配。   
C、装配map:
     <!-- 装配map-->
      <propertyname="maps">
               <map>
                 <entrykey="01">
                   <value>map01</value>
                  </entry>
                  <entrykey="02">
                      <value>map02</value>
                   </entry>
                 </map>
       </property>
   map中的<entry>的数值和<list>以及<set>的一样,可以使任何有效的属性元素,需要注意的是key值必须是String的。
D、装配Properties:
    <!--装配Properties  -->
      <property name="props">
         <props>
           <prop key="01">prop1</prop>
           <prop key="02">prop2</prop>
         </props>
      </property>
E、设置null:
     <!--装配null -->
     <property name="listnull">
        <null/>
     </property>

通过构造方法传递参数:不需要写settter方法也可实例化

   通过参数的顺序:
         <constructor-argindex="0">
            <value>张三</value>
         </constructor-arg>
         <constructor-argindex="1">
             <value>56</value>
          </constructor-arg>
   通过构造函数注入依赖
         <!--通过参数的类型 -->
      <constructor-argtype="java.lang.Integer">
          <value>56</value>
      </constructor-arg>
      <constructor-argtype="java.lang.String">
          <value>张三</value>
       </constructor-arg>


手动注解装配

注解就是spring可以自动帮你把bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。

如果想使用注解装配需要在配置文件中增加如下信息:
<context:annotation-config/>
即完整的为:
<?xml version="1.0" encoding="UTF-8"?><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"       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-3.1.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-3.1.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"><context:annotation-config></context:annotation-config><!--启动注解装配--></beans>
在java代码中使用@Autowired或@Resource注解方式进行装配,这两个注解的区别是:@Autowired 默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired  @Qualifier("personDaoBean")
  private PersonDao  personDao;
eg:
java代码:
package spring.senssic.temp;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;public class B {@Autowiredprivate C c;@Autowired(required = false)// 如果不写false需要写setter方法并在文件中配置propertyprivate int age;@Autowired@Qualifier(value = "date")private Date d;@Overridepublic String toString() {return "--->" + this.age + d;}}

配置:
<?xml version="1.0" encoding="UTF-8"?><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"       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-3.1.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-3.1.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"><context:annotation-config></context:annotation-config><bean id="date" class="java.util.Date"></bean><bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean><bean id="classb" class="spring.senssic.temp.B"></bean></beans>

当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中


@Resource注解和@Autowired一样,也可以标注在字段或属性的setter方法上,但它默认按名称装配。名称可以通过@Resource的name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
java代码:
package spring.senssic.temp;import javax.annotation.Resource;public class D {@Resource(name = "classc")private C c;@Overridepublic String toString() {// TODO Auto-generated method stubreturn "lalalal";}}

配置文件:
<bean id="classc" class="spring.senssic.temp.C" factory-method="createInstance"></bean><bean id="classd" class="spring.senssic.temp.D"></bean>

注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

自动装配

对于自动装配,大家了解一下就可以了,实在不推荐大家使用。例子:
<bean id="..." class="..." autowire="byType"/>
autowire属性取值如下:
byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
constructor与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
autodetect:通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。

通过在classpath自动扫描方式把组件纳入spring容器中管理

spring2.5后为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
要使用自动扫描机制,我们需要打开以下配置信息:
 1、引入context命名空间 需要在xml配置文件中配置以下信息:
  <?xml version="1.0" encoding="UTF-8"?>
<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"
       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-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:component-scan base-package="spring.senssic"></context:component-scan>
 2、在配置文件中添加context:component-scan标签
     <context:component-scanbase-package="spring.senssic"/>
     其中base-package为需要扫描的包(含子包)。
     注:
     1、在使用组件扫描元素时,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor会隐式地被包括进来。 也就是说,连个组件都会被自动检测并织入 - 所有这一切都不需要在XML中提供任何bean配置元数据。
     2、功能介绍
        @Service用于标注业务层组件、
        @Controller用于标注控制层组件(如struts中的action)、
        @Repository用于标注数据访问组件,即DAO组件。
        而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
eg:
                                   //Dao层importorg.springframework.stereotype.Repository;importcom.test.dao.PersonDao;@Repository("personDao") publicclassPersonDaoBean implements PersonDao {}//业务层importjavax.annotation.Resource;importorg.springframework.stereotype.Service;importcom.test.dao.PersonDao;importcom.test.service.PersonService;@Service("personService")publicclassPersonServiceBean implements PersonService {@Resource(name="personDao")privatePersonDao personDao; }



注入方式:   
把DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注   
入时不要new 这个注入的类,因为spring会自动注入,如果手动再new的话会出现错误.





原创粉丝点击