`
huttoncs
  • 浏览: 199129 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring 常用基础点汇总(一)spring引用、bean依赖注入、获取bean容器、初始化bean

 
阅读更多

spring一直在用,但配置一次基本就不去再看了,有些基础点会忘掉,这里做一下简单的记录

一、javaWeb工程的引入spring

     1、web.xml文件中的配置如下

     <!-- 引入spring配置 start -->

<context-param>  

      <param-name>contextConfigLocation</param-name>  

       <param-value>classpath:/applicationContext.xml</param-value>

  </context-param> 

<listener>  

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  

   </listener> 

<!-- 引入spring配置 end -->

     /***-------------------------------------------分割线----------------------------------------------------------*****/

     2、applicationContext.xml文件配置(默认为application-context.xml路径同web.xml,如果有变化务必在                  web.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"

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

"

default-autowire="byName"

>

<description>Spring公共配置</description>

 

<!-- spring 占位符配置 -->

<bean id="propertyConfigurer"  

   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  

<property name="locations">  

       <list>  

           <value>classpath*:jdbc.properties</value>  

       </list>  

      </property>  

</bean> 

 

<!-- 引入 dataSource 配置 -->

<import resource="classpath:dataSource.xml"/>

<!-- 引入 事物管理 配置 -->

<import resource="classpath:transcation.xml"/>

 

<!-- 启用spring的注解扫描 -->

<context:component-scan base-package="com.hutton.client" > 

    <context:exclude-filter expression="org.springframework.stereotype.Controller"  

            type="annotation" /> 

    </context:component-scan>

 

<bean id="testService" class="com.hutton.client.service.impl.TestServiceImpl" >

</bean>

 

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"  

        lazy-init="false" autowire="default" >  

        <property name="dataSource">  

            <ref bean="dataSource" />  

        </property>  

    </bean>

 

<bean id="testDao" class="com.hutton.client.dao.impl.TestDaoImpl" >

</bean>

</beans>

 

applicaContext.xml 中所引用到文件配置如下:

 jdbc.properties文件内容为

  dbDriver = com.mysql.jdbc.Driver

dburl = jdbc:mysql://localhost:3306/test?useUnicode=true&autoReconnect=true&characterEncoding=UTF-8

userName=***

password=***

 

 dataSource.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:jdbc="http://www.springframework.org/schema/jdbc" 

xmlns:tx="http://www.springframework.org/schema/tx" 

xmlns:repository="http://www.springframework.org/schema/data/repository" 

xmlns:aop="http://www.springframework.org/schema/aop"

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/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd 

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 

http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

<description>数据源配置</description>

 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName" value="${dbDriver}" />

<property name="url" value="${dburl}" />

<property name="username" value="${userName}" />

<property name="password" value="${password}"/>

</bean>

 

</beans>

 

/****--------------------------------------分割线-------------------------------------------------***/

 

二、spring常用的集中注入方式

1、set 方式注入,最常用的一种方式,格式如前面的

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"  

        lazy-init="false" autowire="default" >  

        <property name="dataSource">  

            <ref bean="dataSource" />  

        </property>  

    </bean>

2、构造器注入,这种方式的注入是指带有参数的构造函数注入,例如:

在XML文件中同样不用<property>的形式,而是使用<constructor-arg>标签,ref属性同样指向其它<bean>标签的name属性:

  1. <!--配置bean,配置后该类由spring管理-->  
  2.     <bean name="springAction" class="com.bless.springdemo.action.SpringAction">  
  3.         <!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->  
  4.         <constructor-arg ref="springDao"></constructor-arg>  
  5.         <constructor-arg ref="user"></constructor-arg>  
  6.     </bean>  
  7.         <bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>  
  8.          <bean name="user" class="com.bless.springdemo.vo.User"></bean>
解决构造方法参数的不确定性,你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理:
下面是设置index,就是参数位置:
  1. <bean name="springAction" class="com.bless.springdemo.action.SpringAction">  
  2.         <constructor-arg index="0" ref="springDao"></constructor-arg>  
  3.         <constructor-arg index="1" ref="user"></constructor-arg>  
  4.     </bean>  
  1. public class SpringAction {  
  2.     //注入对象springDao  
  3.     private SpringDao springDao;  
  4.     private User user;  
  5.       
  6.     public SpringAction(SpringDao springDao,User user){  
  7.         this.springDao = springDao;  
  8.         this.user = user;  
  9.         System.out.println("构造方法调用springDao和user");  
  10.     }  
  11.           
  12.         public void save(){  
  13.         user.setName("卡卡");  
  14.         springDao.save(user);  
  15.     }  
  16. }  

 

3、自动装配(注解方式)

spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct以及@PreDestroy。

  @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

  @Resource装配顺序

  (1). 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常

  (2). 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常

  (3) 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常

  (4) 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

 

@Autowired 与@Resource的区别:

 

(1) @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

(2)、 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired()

@Qualifier("baseDao")

private  BaseDao baseDao;

 

(3)@Resource(这个注解属于J2EE的),默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

 

@Resource(name="baseDao")

 

private BaseDao baseDao;

 

 4、自动装配(通过配置文件方式)

在spring的配置文件中,申明里配置一个属性.default-autowire="byName"(通过名字自动装配)  ,具体见前面的配置。

default-autowire="x"

x有4个选择:byName,byType,constructor和autodetect 

(1). byName:

Service.java

public class Service

{

    Source source;

    public void setSource(Source source)

    {

        this.source = source;

    }

}

applicationContext.xml

<beans

   ...

   default-autowire="byName">

    <bean id="source" class="cn.hh.spring.DBCPSource" scope="prototype"/>

    <bean id="service" class="cn.hh.spring.Service" scope="prototype">

    </bean>

</beans>

cn.hh.spring.DBCPSource实现了Source接口

xml中并没有给 bean service配Source属性,但在beans中设置了autowire="byName",这样配置文件会自

 

动根据 cn.hh.spring.Service 中的setSource找bean id="Source"的bean ,然后自动配上去,如果没找

 

到就不装配。

注意:byName的name是java中setXxxx 的Xxxx, 和上面设置的Source source中source拼写毫无关系,完

 

全可以是

public class Service

{

    Source source1;

    public void setSource(Source source1)

    {

        this.source1 = source1;

    }

}

(2). byType:

Service.java同上

applicationContext.xml

<beans

   ...

   default-autowire="byType">

    <bean id="dbcpSource" class="cn.hh.spring.DBCPSource" scope="prototype"/>

    <bean id="service" class="cn.hh.spring.Service" scope="prototype">

    </bean>

</beans>

同样没有配置setSource,autowire改成 "byType",配置文件会找实现了Source接口的bean,这里 

 

cn.hh.spring.DBCPSource 实现了Source接口,所以自动装配,如果没找到则不装配。

如果同个配制文件中两个bean实现了Source接口,则报错。

这里的 Type是指setSource(Source source)中参数的类型。

(3). constructor:

试图在容器中寻找与需要自动装配的bean的构造函数参数一致的一个或多个bean,如果没找到则抛出异常

 

(4). autodetect:

首先尝试使用constructor来自动装配,然后再使用byType方式。

 

/****--------------------------------------分割线-------------------------------------------------***/

 

三、获取spring容器的几种常用方法

    1、通过beanFactory获取,这是最基本的方式,很少使用,但是也不推荐使用,仅做一下了解

     具体测试类如下:

/**

 * 类BeanFactoryTest.java的实现描述:TODO 类实现描述

 * 

 * <pre>

 * 注意,ApplicationContext能够自动辨认和应用在其上部署的实现了BeanFactoryPostProcessor的bean。这就意味着,当使用ApplicationContext的时候应用PropertyPlaceholderConfigurer会非常的方便。由于这个原因,建议想要使用这个或者其他bean、Factory postprocessor的用户使用ApplicationContext 代替BeanFactroy。

 * </pre>

 * 

 */

public class BeanFactoryTest {

 

    static Logger logger = LoggerFactory.getLogger(BeanFactoryTest.class);

 

    public static void main(String[] args) {

        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        Resource res = resolver.getResource("classpath:applicationContext.xml");

        try {

            logger.info("spring 配置文件地址:{}", res.getURL().toString());

            @SuppressWarnings("deprecation")

            XmlBeanFactory bf = new XmlBeanFactory(res);

 

            // 如果要在BeanFactory中使用,bean factory post-processor必须手动运行:

            PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();

            cfg.setLocation(new FileSystemResource("src/main/resources/jdbc.properties"));

            cfg.postProcessBeanFactory(bf);

            logger.info("init BeanFactory.");

 

            TestService service = (TestService) bf.getBean("testService");

            System.out.println("testService bean is ready for use!");

            System.out.println(service.sayHello("lisi"));

        } catch (IOException e) {

            logger.error("处理异常", e);

        }

 

    }

}

 

2、在初始化时保存applicationContext

   代码:

ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");

ac.getBean("beanId");

或者

ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

 

说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。在本地测试时常用到的方法

 

3、实现接口ApplicationContextAware

说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。spring的单元测试类AbstractJUnit4SpringContextTests就是采用的这种方式。

Spring初始化时,会通过该方法将ApplicationContext对象注入。

 

4、继承自抽象类ApplicationObjectSupport

说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。

Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入

 

5、继承自抽象类WebApplicationObjectSupport

说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext

 

6、通过Spring提供的工具类获取ApplicationContext对象

代码:

import org.springframework.web.context.support.WebApplicationContextUtils;

ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);

ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);

ac1.getBean("beanId");

ac2.getBean("beanId");

说明:

这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。

 

上面两个工具方式的区别是,前者在获取失败时抛出异常,后者返回null。

 

7、不依赖于servlet,不需要注入的方式

WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); 

  wac.getBean(beanID);

 

注意一点,在服务器启动时,Spring容器初始化时,不能通过以下方法获取Spring 容器,仅在运行期获取,如需细节可以观看源码org.springframework.web.context.ContextLoader

 

/***--------------------------------------------------  分割线 ---------------------------------------***/

虽 然,spring提供了三种方法3、4、5可以实现在普通的类中继承或实现相应的类或接口来获取spring 的ApplicationContext对象,但是在使用是一定要注意实现了这些类或接口的普通java类一定要在Spring 的配置文件application-context.xml文件中进行配置。否则获取的ApplicationContext对象将为null。

 

/***-----------------------------------------------------分割线 --------------------------------------------------------***/

 

四、spring 初始化bean的优先级

参考另外一篇博文 http://huttoncs.iteye.com/blog/2244285

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics