Spring基本使用方法_Bean对象

Spring基本使用方法_Bean对象

Struts与Hibernate可以做什么事?
Struts
MVC中控制层解决方案.可以进行请求数据自动封装,类型转换,文件上传,效验.....
Hibernate
持久层的解决方案
,m.VXZCM可以做到把对象保存到数据库,从数据中取出的是对象.

传统的开发模式
基于MVC模式进行项目开发,基于MVC的项目框架结构:Entity/dao/service/action

1.Spring简单使用

1.1.专业术语了解

1.组件/框架设计
侵入式设计:
引入了框架,对现有的类的结构有影响,即需要实现或继承某些特定类.例如:Struts框架
非侵入式设计:
引入了框架,对现实有的类结构没有影响,例如:Hibernate框架/Spring框架

2.控制反转和依赖注入
Inversion on Control,控制反转IOC.
对象的创建交给外部容器完成,这个就叫做控制反转.
依赖注入,dependency injection.处理对象的依赖关系
区别:
控制反转:解决对象创建的问题.[对象创建交给别人]
依赖注入:在创建完对象后,对象的关系处理就是依赖注入[通过set方法依赖注入]

3.AOP
面向切面编程:切面,简单来说可以理解为一个类,由很多重复代码形成的类.
切面举例:事务,日志,权限.

1.2.Spring概述

Spring是一个非常活跃的开源框架,他是一个基于IOC和AOP来架构多层JavaEE系统的框架,它的主要目的是简化企业开发.
Spring以一种非侵入式的方式来管理你的代码,Spring提倡"最少侵入",这也就意味着你可以适当的时候安装或者卸载Spring.
Spring框架,可以解决对象创建以及对象之间依赖关系的一种框架爱.且可以和其他框架一起使用:Spring和Struts,Spring和Hibernate,起到整合作用的一个框架.
在项目中使用Spring的目的是降低组件之间的耦合度,实现软件各层之间的解耦.

Spring框架被分为六大模块,分别用来解决不同的问题.六大模块如下:

1.Spring Core,Spring的核心功能.

IOC容器,解决对象创建以及依赖关系
包含并管理应用对象的配置和生命周期,可以配置每一个bean如何被创建,也可以配置每一个bean是只有一个实例,还是每次需要时都生成一个新的实例,以及他们是如何相互关联的

2.Spring Web,Spring对Web模块的支持.

可以与Struts整合,让Struts的action创建交给Spring
提供了子弟的Spring MVC和对显示层框架的集合支持

3.Spring DAO,Spring对jdbc的支持

使用JdbcTemplate来简化数据操作

4.Spring ORM,Spring对ORM的支持.

提供了对主流的对象映射关系框架的支持
既可以与Hibernate整合(session)
也可以使用spring的对Hibernate操作的封装

5.Spring AOP,切面编程.

采用了面向切面编程来实现很多基础但是与业务逻辑无关的功能的解耦,比如:事务管理,日志,权限验证

6.Spring JEE,Spring对JavaEE其他模块的支持.

对java企业级开发提供了一些解决方案,如EJB,JMS等

1.3.开发步骤

Spring各个版本中:
在3.0以上的版本中,源码有Spring中相关的所有包(Spring功能包+依赖包),如2.5版本
在3.0以上的版本中,源码只有Spring的核心功能包(没有依赖包),如果要用到依赖包,需要单独下载

1.下载源码:
此处使用3.2的版本:
spring-framework-3.2.5.RELEASE
Spring必须要引入的jar文件有5个,分别是:

  • commons-logging-1.1.3.jar 日志管理
  • spring-beans-3.2.5.RELEASE.jar bean节点
  • spring-context-3.2.5.RELEASE.jar spring上下文节点
  • spring-core-3.2.5.RELEASE.jar spring核心功能
  • pring-expression-3.2.5.RELEASE.jar spring表达式相关表

2.配置
核心配置文件是:applicationContext.xml或者bean.xml,一般都是前者,JavaBean对象在这里面被创建,然后在java中调用就可以了.
假设已经存在一个User的JavaBean代码,需要创建对象,然后在java中使用
applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--IOC容器的配置,要创建的所有的对象都在这里配置-->
    <bean id="user" class="a_hello.User"></bean>
</beans>

使用API:

/**
 * 从IOC容器创建对象
 */
public class app {

    //1. 通过工厂类得到IOC容器创建的对象
    @Test
    public void testIOC() throws Exception{
        //创建对象
//        User user = new User();

        //现在把对象的创建交给容器
        Resource resource = new ClassPathResource("a_hello/applicationContext.xml");
        //创建容器对象(Bean的工厂),IOC容器=工厂类+applicationContext.xml
        BeanFactory factory = new XmlBeanFactory(resource);
        //得到容器创建的对象
        User user = (User) factory.getBean("user");

        System.out.println(user.getId());

    }

    //2.(方便)直接得到IOC容器对象
    @Test
    public void testAc() throws Exception{
        //得到IOC容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("a_hello/applicationContext.xml");
        //从容器中获取bean
        User user = (User) ac.getBean("user");

        System.out.println(user.getId());
    }
}

1.4.bean对象创建的细节

在applicationContext.xml中创建对象,要注意一些细节:


/**
 * Bean对象创建的细节
 */
public class AppBean {

    /**
     *1.对象创建:单例/多例
     * 在applicationContext.xml配置文件中,设置scope参数
     * scope="singleton",默认值,即默认是单例 [service/dao等工具类时使用单例]
     * scope="prototype",多例, [Action对象时用多例]
     */

    /**
     *2.什么时候创建
     * scope="singleton",在启动时(容器创建之前),就已经创建了bean,且整个应用只有一个对象
     * scope="prototype",先创建容器,只有在用到对象的时候,才创建对象.
     */

    /**
     * 3.是否延迟创建
     * 在applicationContext.xml配置文件中,设置lazy-init参数
     * lazy-init="false" 默认为false,不延迟创建,在启动的时候就创建对象
     * lazy-init="true" 延迟初始化,在用到对象的时候才创建对象
     * lazy-init参数只对单例有效
     */

    /**
     *4.创建对象之后,初始化/销毁
     * init-method="init_user",init_user是user中的一个方法,对应对象的init_user方法,在对象创建之后执行
     * destroy-method="destroy_user",destory_user是user中的一个方法,在调用容器对象的destriy方法时执行(容器用类实现)
     */
    @Test
    public void testAc() throws Exception{
        //得到IOC容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("a_hello/applicationContext.xml");
        System.out.println("容器创建成功");
        //从容器中获取bean
        User user1 = (User) ac.getBean("user");
        User user2 = (User) ac.getBean("user");

        //scope="singleton"时,返回true
        //scope="prototype"时,返回false
        System.out.println(user1==user2);
        
        //销毁容器对象,调用了destroy-method参数中的方法
        ac.destroy();
    }
}

applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--IOC容器的配置,要创建的所有的对象都在这里配置-->
    <bean id="user" class="a_hello.User" scope="singleton" lazy-init="false" init-method="init_user" destroy-method="destroy_user"></bean>
</beans>

2.Spring IOC容器功能

Spring IOC容器,是Spring核心内容,属于Spring Core部分.作用是:创建对象以及处理对象的依赖关系
下面分别看创建对象和依赖关系

2.1.创建对象

IOC容器创建对象的几种方式:
1.调用无参数构造器
2.带参数构造器
3.工厂创建对象,分为工厂类的静态方法创建对象和非静态方法创建对象

代码示例:
用java写一个工厂类:ObjectFactory.java

public class ObjectFactory {

    //实例方法创建对象
    public User getInstance(){
        return new User(100,"调用实例方法");
    }

    //静态方法创建对象
    public static User getStaticInstance(){
        return new User(100,"调用静态方法");
    }
}

applicationContext.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">



    <!--对象创建-->

    <!--1.默认无参数构造器-->
    <!--<bean id="user" class="a_hello.User"/>-->

    <!--2.带参数构造器-->
    <bean id="user1" class="a_hello.User">
        <!--type的值,如果是基本类型用常用的类型就可以,如果是引用类型就用类型的全名-->
        <constructor-arg value="100" index="0" type="int"></constructor-arg>
        <constructor-arg value="Jack" index="1" type="java.lang.String"></constructor-arg>
    </bean>

    <!--定义一个字符串,值是"Jack",String s = new String("Jack")-->
    <bean id="str" class="java.lang.String">
        <constructor-arg value="Jack"/>
    </bean>
    <bean id="user2" class="a_hello.User">
        <constructor-arg index="0" type="int" value="100"/>
        <constructor-arg index="1" type="java.lang.String" ref="str"/>
    </bean>


    <!--3.工厂类创建对象-->
    <!--3.1.工厂类 实例方法-->
    <!--先创建工厂-->
    <bean id="factory" class="a_hello.ObjectFactory"/>
    <!--再创建user对象,用factory的实例方法-->
    <bean id="user3" factory-bean="factory" factory-method="getInstance"/>

    
    <!--3.2.工厂类 静态方法-->
    <!--class 指定的就是工厂类型-->
    <!--factory-method 一定是工厂里面的静态方法-->
    <bean id="user4" class="a_hello.ObjectFactory" factory-method="getStaticInstance"/>


</beans>

2.2.对象依赖关系

上面已经可以创建一个对象了,但是如何给对象的属性赋值呢?
1.通过构造函数(上面已经有例子了)
2.通过set方法给属性注入值
3.p名称空间
4.自动装配(了解)
5.注解

0.通过构造函数

    <!--1.通过构造函数-->
    <bean id="user" class="b_property.User">
        <constructor-arg value="100"></constructor-arg>
        <constructor-arg value="Jack"></constructor-arg>
    </bean>

1.(常用)Set方法注入值

    <!--2.通过set方法给属性赋值-->
    <bean id="user1" class="b_property.User">
        <!--user.id的赋值-->
        <property name="id" value="99"/>
        <!--user.name的赋值-->
        <property name="name" value="Jerry"/>
    </bean>

测试类:

 @Test
    public void testSet() throws Exception{
        //创建容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("b_property/applicationContext.xml");

        //获取容器中的对象
        User user = (User) ac.getBean("user1");

        System.out.println(user);
    }

案例:在一个项目中,需要在action/service/dao三个地方创建对象.配置如下:

    <!-- dao 对象创建 -->
    <bean id="userDao" class="b_property.UserDao"></bean>

    <!-- service 对象创建,并调用dao-->
    <bean id="userService" class="b_property.UserService">
        <property name="userDao" ref="userDao"></property>
    </bean>

    <!-- action 对象创建,并调用service -->
    <bean id="userAction" class="b_property.UserAction">
        <property name="userService" ref="userService"></property>
    </bean>

2.内部bean
使用内部bean的方法,同样可以实现action/service/dao

    <!--内部bean-->
    <bean id="userAction" class="b_property.UserAction">
        <property name="userService">
            <bean class="b_property.UserService">
                <property name="userDao">
                    <bean class="b_property.UserDao"></bean>
                </property>
            </bean>
        </property>
    </bean>

与Set注入的达到的效果是一样的,区别在于如果不同的action要使用service时候,需要再写一遍.且不易维护

3.p 名称空间注入属性值(优化)
使用p名称空间也可以达到上面同样的效果,并得到了优化

    <!-- 对象属性赋值 -->
    <!--
        给对象属性注入值也可以使用 p 名称空间给对象的属性注入值
          注意:spring3.0以上版本才支持
     -->
    <bean id="userDao" class="b_property.UserDao"></bean>

    <bean id="userService" class="b_property.UserService" p:userDao-ref="userDao"></bean>

    <bean id="userAction" class="b_property.UserAction" p:userService-ref="userService"></bean>


    <!-- 传统的注入:
     <bean id="user" class="b_property.User" >
         <property name="name" value="xxx"></property>
     </bean>
    -->
    <!-- p名称空间优化后 -->
    <bean id="user" class="b_property.User" p:name="Jack0001"></bean>

4.自动装配(了解)

根据名称自动装配
autowire="byName"会自动去IOC容器中查找与属性同名的引用的对象,并自动注入.

代码示例:

    <!--自动装配-->
    <bean id="userDao" class="d_auto.UserDao"></bean>
    <bean id="userService" class="d_auto.UserService" autowire="byName"></bean>
    <!-- 根据“名称”自动装配: userAction注入的属性,会去ioc容器中自动查找与属性同名的对象 -->
    <bean id="userAction" class="d_auto.UserAction" autowire="byName"></bean>

也可以把autowire="byName"定义到全局,这样就不用每个bean节点都去写autowire="byName"
代码示例:

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">   根据名称自动装配(全局)
	
	<!--自动装配 -->  
	<bean id="userDao" class="d_auto.UserDao"></bean>	
	<bean id="userService" class="d_auto.UserService"></bean>
	<bean id="userAction" class="d_auto.UserAction"></bean>
</beans> 

根据类型自动装配
除了根据相似的名称自动装配外,还可以根据类型自动装配,使用的参数为:autowire="byType".
此时必须确保该类型在IOC容器中只有一个对象,否则,报错!

示例代码:

<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byType">
	
	<!-- ###############自动装配############### -->  
	<bean id="userDao" class="d_auto.UserDao"></bean>	
	<bean id="userService" class="d_auto.UserService"></bean>
	
	<!-- 如果根据类型自动装配: 必须确保IOC容器中只有一个该类型的对象 -->
	<bean id="userAction" class="d_auto.UserAction"></bean>
	
	
	<!--   报错: 因为上面已经有一个该类型的对象,且使用了根据类型自动装配
	<bean id="userService_test" class="d_auto.UserService" autowire="byType"></bean>
	 -->
</beans>  

总结:
Spring提供的自动专配主要是为了简化配置;但是不利于后期的维护.一般推荐使用

5.注解
Spring的IOC容器的配置也可以使用注解来简化操作.
使用注解的步骤:
1.applicationContext.xml文件中引入context名称空间

mlns:context="http://www.springframework.org/schema/context"
2.开始注解扫描

<!--开始注解扫描-->
    <!--base-package="b_property":扫描b_property包下的所有类-->
    <context:component-scan base-package="b_property"/>

3.使用注解,通过注解的方式,把对象加入

创建对象以及处理对象依赖关系,相关的注解:

  • @component:指定把一个对象加入IOC容器
  • @Respository:作用同@component;在持久层使用
  • @Service:作用同@component;在业务逻辑层使用
  • @Controller:作用同@component;在控制层使用
  • @Resource:属性注入

总结:
1.使用注解,可以简化配置,且可以把对象加入
容器,及处理依赖关系
2.注解可以和xml配置一起是使用.

原文地址:https://www.cnblogs.com/cenyu/p/6287904.html