spring(一)之IOC

总目录

(一)spring框架概述以及spring中基于XML的IOC配置
(二)spring中基于注解的IOC和IOC案例
(三)spring中的aop和基于XML以及注解的AOP配置
(四)spring的JdbcTemplate以及Spring事务控制

1 spring的概述

  • spring是什么东西
  • spring的两大核心
  • spring的发展历程和优势
  • spring的体系结构

2 程序的耦合及解耦

  • 曾经案例中问题
  • 工厂模式解耦

3 IOC概念和spring中的IOC

  • spring中基于XML的IOC环境搭建

4 依赖注入(Dependency Injection)

1 spring概述

IOC 反转控制 AOP面向切面编程 两大核心

在这里插入图片描述

spring 优势

  1. 方便解耦,简化开发
  2. AOP编程的支持
  3. 声明式事务的支持
  4. 方便程序的测试
  5. 方便集成各种优秀框架
  6. 降低JavaEE API的使用难度
  7. 学习spring源码(以后)

spring的体系结构

spring框架图=================

2 程序的耦合及解耦

编写jdbc的工程代码用于分析程序的耦合

public class JdbcDemo01 {
    public static void main(String[] args) throws Exception {
        //1注册驱动
        DriverManager.registerDriver(new com.mysql.jdbc.Driver());
        //2获取连接
        Connection conn =DriverManager.getConnection("jdbc:mysql://localhost:3306/spring","root","xgh961120");
        //3获取操作数据库的预处理对象
        PreparedStatement pstm = conn.prepareStatement("select * from account");
        //4执行SQL,得到结果集
        ResultSet rs =pstm.executeQuery();
        //5 遍历结果集
        while (rs.next()){
            System.out.println(rs.getString("name"));
        }
        //6释放资源
        rs.close();
        pstm.close();
        conn.close();
    }
}

程序的耦合

耦合:简单的认为时程序间的依赖关系

包括

  • 类之间的依赖
  • 方法之间的依赖
解耦:降低程序间的依赖关系

实际开发中应该做到,编译器不依赖,运行时才依赖

比如
注册驱动编译器有依赖,如果去除mysql的驱动,则在编译期间,就报错,因为依赖具体的驱动类

 DriverManager.registerDriver(new com.mysql.jdbc.Driver());

解耦的方法:
只依赖一个字符串
Class.forName(“com.mysql.jdbc.Driver”);
出去mysql的驱动,在编译的时候可以通过,到运行的时候才报异常

解耦的思路:
第一步:使用反射来创建对象,而避免使用new关键字
第二步:通过读取配置文件来获取要创建的对象全限定类名

曾经代码中的问题

对于一个MVC三层架构,原来的思路在调用过程中也犯了跟JDBC耦合同样的错误new了下一层的对象
在这里插入图片描述

持久层

/*
账户的持久层接口
 */
public interface IAcountDao {
    /**
     * 模拟保存接口
     */
    void saveAccount();
}

账户的持久层实现类

public class AccountDaoImpl implements IAcountDao{
    public void saveAccount() {
        System.out.println("保存了账户");
    }
}	

业务层调用调用持久层就犯了错误

public interface  IAcountService{
    /*
    模拟保存账户
     */
    void saveAccount();

}

账户的业务层实现类,业务层调用持久层
注意:业务层在调用持久层的时候犯了同数据库一样的问题,new了持久层的具体实现类

public class AccountServiceImpl implements IAcountService {
        private IAcountDao accountDao=new AccountDaoImpl();
    public void saveAccount() {
        accountDao.saveAccount();
    }
}

表现层也同样耦合

  • 模拟一个表现层,用于调用业务层,在实际开发中这应该是一个servlet
  • 表现层在调用业务层的时候也犯了同样的错误new了业务层的具体实现类

public class Client {
    public static void main(String[] args) {
        IAcountService as = new AccountServiceImpl();
        as.saveAccount();

    }
}

只要AccountsDaoimpl,AccountServiceImpl实现类去掉,整个工程在编译阶段就报错

怎么解除依赖关系呢?

使用工厂

一个创建Bean对象的工厂

Bean在计算机英语里,有可重用组件的含义(软件开发中,一个项目也有很多部分组成)
JavaBean:用Java语言编写的可重用组件。
javabean >实体类

一个创建Bean对象的工厂,它就是创建我们的service和dao的对象。
如何创建?
1. 需要一个配置文件来配置我们的service和dao
配置的内容:唯一标志(用什么来去全限定类名)=全限定类名(Key=Value)
2. 通过读取配置文件的配置内容,利用反射创建bean对象

   配置文件可以是XML,可以是properties
创建配置文件,存放唯一标志和全限定类名

bean.properties

accountService =com.tju.service.impl.AccountServiceImpl
accountDao = com.tju.dao.impl.AccountDaoImpl
一个创建Bean对象的工厂类

利用从配置文件读取全限定类名创建我们的service和dao对象的。

public class BeanFactory {
    //定义一个Properties对象
    private static Properties props;
    //使用静态代码块为Properties对象赋值
    static {

        try {
            //实例化对象
            props = new Properties();
            //获取properties文件的流对象
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);
        } catch (Exception e) {
           throw new ExceptionInInitializerError("初始化properties失败");
        }


    }

    /**
     * 根据Bean名称获取bean对象
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName){

    Object bean=null;
    try {
        String beanPath = props.getProperty(beanName);
        //用反射的方式创建对象,需要从创建的类里得到全限定类名
        bean=Class.forName(beanPath).newInstance();
    }catch (Exception e){

        e.printStackTrace();
    }

    return bean;
}
}
首先改造表现层中的耦合语句
public class Client {
    public static void main(String[] args) {
        //原来的耦合语句IAcountService as = new AccountServiceImpl();
        //解耦的方法
        IAcountService as = (IAcountService)BeanFactory.getBean("accountService");
        as.saveAccount();
    }
}
改造业务层的耦合结果
public class AccountServiceImpl implements IAcountService {
//原来的耦合语句 private IAcountDao accountDao=new AccountDaoImpl();
    //解耦
    private IAcountDao accountDao= (IAcountDao)BeanFactory.getBean("accountDao");
    public void saveAccount() {
        accountDao.saveAccount();
    }
}

这样在没有实体类AccountServiceImpl,AccountDaoImpl的话不会编译报错,只会运行时发出异常,一定程度解耦

分析工厂模式中的问题并改造

问题:

在client中进行改造:

public class Client {
    public static void main(String[] args) {
        for(int i=0;i<5;i++){
            IAcountService as = (IAcountService)BeanFactory.getBean("accountService");
            System.out.println(as);

        }

    }
}

结果:
com.tju.service.impl.AccountServiceImpl@880ec60
com.tju.service.impl.AccountServiceImpl@3f3afe78
com.tju.service.impl.AccountServiceImpl@7f63425a
com.tju.service.impl.AccountServiceImpl@36d64342
com.tju.service.impl.AccountServiceImpl@39ba5a14
证明是多例的

在刚才的基础上
Client.java

public class Client {
    public static void main(String[] args) {
        for(int i=0;i<5;i++){
            IAcountService as = (IAcountService)BeanFactory.getBean("accountService");
            System.out.println(as);
             as.saveAccount();
        }
    }
}

AccountServiceImpl.java

public class AccountServiceImpl implements IAcountService {


    private IAcountDao accountDao= (IAcountDao)BeanFactory.getBean("accountDao");
    private int i=1;

    public void saveAccount() {
        accountDao.saveAccount();
        System.out.println(i);
        i++;
    }
}

执行结果

com.tju.service.impl.AccountServiceImpl@880ec60
保存了账户
1
com.tju.service.impl.AccountServiceImpl@3f3afe78
保存了账户
1
com.tju.service.impl.AccountServiceImpl@7f63425a
保存了账户
1
com.tju.service.impl.AccountServiceImpl@36d64342
保存了账户
1
com.tju.service.impl.AccountServiceImpl@39ba5a14
保存了账户
1

每个对象都是单独的示例,Service的实例对象都是新创建的,所以一直重新初始化i,i始终为1,所以是多例模式
多例多项被创建多次,执行效率低

如果创建对象是单例的,对象只被创建一次,类中的成员也就只会初始化一次,单例对象有线程问题

在service层和dao层没有在单例对象可以改变的类成员
我们还是把变量定义到方法中来
每次方法都会初始化,所以得到的i还是1

public class AccountServiceImpl implements IAcountService {


    private IAcountDao accountDao= (IAcountDao)BeanFactory.getBean("accountDao");
    

    public void saveAccount() {
     int i=1;
        accountDao.saveAccount();
        System.out.println(i);
        i++;
    }
}
在BeanFactory类中

bean=Class.forName(beanPath).newInstance(); //默认每次都会调用默认构造函数创建对象

调整的角度就是不需要每次都创建对象,只需要创建对象一次

只能用一次newInstance()创建对象
创建好立即存起来,用什么存?

用map存
重新写类BeanFactory

public class BeanFactory {
    //定义一个Properties对象
    private static Properties props;

    //定义一个Map,用于存放我们要创建的对象,我们把它称之为容器
    private static Map<String,Object> beans;

    //使用静态代码块为Properties对象赋值
    //静态代码块只在类加载的时候执行一次
    static {

        try {
            //实例化对象
            props = new Properties();
            //获取properties文件的流对象
            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            props.load(in);

            //实例化我们的容器
            beans = new HashMap<String,Object>();
            //取出配置文件中所有的key
            Enumeration keys = props.keys();
            //遍历这个枚举
            while(keys.hasMoreElements()){
                //取出每个Key
                String key =keys.nextElement().toString();
                //根据key获取value
                String beanPath =props.getProperty(key);
                //反射创建对象
                Object value =Class.forName(beanPath).newInstance();
                //把key和value存入容器之中
                beans.put(key,value);

            }
        } catch (Exception e) {
           throw new ExceptionInInitializerError("初始化properties失败");
        }


    }


/**
 * 对原来的getBean(String beanName)方法进行改造
 * 根据bean的名称获取单例对象
 */
    public static Object getBean(String beanName){

           return beans.get(beanName);
    }
}

打印结果
com.tju.service.impl.AccountServiceImpl@30c7da1e
com.tju.dao.impl.AccountDaoImpl@5b464ce8
保存了账户
1
com.tju.service.impl.AccountServiceImpl@30c7da1e
com.tju.dao.impl.AccountDaoImpl@5b464ce8
保存了账户
2
com.tju.service.impl.AccountServiceImpl@30c7da1e
com.tju.dao.impl.AccountDaoImpl@5b464ce8
保存了账户
3
com.tju.service.impl.AccountServiceImpl@30c7da1e
com.tju.dao.impl.AccountDaoImpl@5b464ce8
保存了账户
4
com.tju.service.impl.AccountServiceImpl@30c7da1e
com.tju.dao.impl.AccountDaoImpl@5b464ce8
保存了账户
5
此时变成单例模式,同一个类反复操作类成员变量,不需要反复创建对象
在这里插入图片描述

2 IOC的概念和作用

两种创建对象的方式

主动情况下,直接new,和资源联系,明显依赖
依赖工厂,不依赖资源,这就是IOC
在这里插入图片描述

为什么叫控制反转

原来在Service层
我想new就new,主动权在我
private IAcountDao accountDao=new AccountDaoImpl();
现在必须依赖于工厂,创建对象必须给全限定类名,控制权在工厂,叫控制反转
private IAcountDao accountDao=new AccountDaoImpl();

控制反转:

把创建对象的权利交给框架,是框架的重要特征。它包括依赖注入和依赖查找

spring的IOC解决程序耦合

spring基于XML的IOC环境搭建和入门

spring的jar包
在这里插入图片描述

整个工程的依赖
在这里插入图片描述

在配置文件中从spring的配置文件找到约束导入

<?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">

<!-- 把对象的创建交给spring来管理 id是唯一标志,class是全限定类名-->
 <bean id="accountService" class="com.tju.service.impl.AccountServiceImpl"></bean>

    <bean id="accountDao" class="com.tju.dao.impl.AccountDaoImpl"></bean>

</beans>

接下来获取spring创建核心容器的map,并根据id获取对象

spring的类视图
在这里插入图片描述

 //1.获取核心容器对象,配置文件在根路径下直接写文件名字
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    //2.根据id获取Bean对象,两种方式一种是直接获得类的对象自己强转,一种是传字节码已经强转
    IAccountService as  = (IAccountService)ac.getBean("accountService");
    IAccountDao adao = ac.getBean("accountDao",IAccountDao.class);

    System.out.println(as);
    System.out.println(adao);

结果
com.tju.service.impl.AccountServiceImpl@1dac5ef
com.tju.dao.impl.AccountDaoImpl@5c90e579

我们要做的就是配置文件和获取核心容器对象

ApplicationContext的三个实现类

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ApplicationContext的三个常用实现类:
  • ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。
  • FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\zhy\\Desktop\\bean.xml");
  • AnnotationConfigApplicationContext:它是用于读取注解创建容器的。
BeanFactory和ApplicationContext的区别

核心容器的两个接口引发出的问题:

ApplicationContext: 单例对象适用 实际开发种采用此接口

它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
ApplicationContext ac = new ClassPathXmlApplicationContext(“bean.xml”);
一执行完这句话,配置文件被读完,同时Service和Dao的实现类被创建

BeanFactory: 多例对象使用

它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。

//--------BeanFactory----------
        //从类路径下读取配置文件
          Resource resource = new ClassPathResource("bean.xml");
          //根据配置文件创造工厂
          BeanFactory factory = new XmlBeanFactory(resource);
          //什么时候用,什么时候创建对象,只要在调用的时候,Servic实现类或者Dao的实现类才会被创建
         IAccountService as1  = (IAccountService)factory.getBean("accountService");
         System.out.println(as1);

spring中的bean细节之三种创建Bean对象的方式

创建Bean的三种方式

第一种方式:使用默认构造函数创建。

在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。

<bean id="accountService" class="com.tju.service.impl.AccountServiceImpl"></bean>
第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)

在这里插入图片描述

  • 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
public class InstanceFactory {

    public IAccountService getAccountService(){
        return new AccountServiceImpl();
    }
}

这样的话取得是工厂类对象

  <bean id="instanceFactory" class="com.tju.factory.InstanceFactory"></bean>

我们创建实例化对象accountService,需要调用工厂的方法

<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
  • 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
public class StaticFactory {

    public static IAccountService getAccountService(){

        return new AccountServiceImpl();
    }
}
<bean id="accountService" class="com.tju.factory.StaticFactory" factory-method="getAccountService"></bean>

spring中的bean中的细节之作用范围

spring的默认对象是单例的
<bean id="accountService" class="com.tju.service.impl.AccountServiceImpl" scope="prototype"></bean>
public static void main(String[] args) {
    //1.获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
  
    //2.根据id获取Bean对象
    IAccountService as1  = (IAccountService)ac.getBean("accountService");
    IAccountService as2  = (IAccountService)ac.getBean("accountService");
    System.out.println(as1==as2);

}

结果是True Bean对象只创建了一次,两个对象是同一个

bean的作用范围调整

bean标签的scope属性:

  • 作用:用于指定bean的作用范围
  • 取值: 常用的就是单例的和多例的
    • singleton:单例的(默认值)
    • prototype:多例的
    • request:作用于web应用的请求范围
    • session:作用于web应用的会话范围
    • global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
      全局Session图
      在这里插入图片描述
更改成多例:
 <bean id="accountService" class="com.tju.service.impl.AccountServiceImpl" scope="prototype"></bean>

结果False,Bean对象多次创建,两个对象不同

Spring bean中的生命周期

bean对象的生命周期

  • 单例对象
    • 出生:当容器创建时对象出生,立即
    • 活着:只要容器还在,对象一直活着
    • 死亡:容器销毁,对象消亡
    • 总结:单例对象的生命周期和容器相同
  • 多例对象
    • 出生:当我们使用对象时spring框架为我们创建,延迟
    • 活着:对象只要是在使用过程中就一直活着。
    • 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收

单例对象:

  <bean id="accountService" class="com.tju.service.impl.AccountServiceImpl"
          scope="singleton" init-method="init" destroy-method="destroy"></bean>

测试单例对象

   public static void main(String[] args) {
        //1.获取核心容器对象
//       不使用这种多态形式,无法调用子类的特有关闭方法 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      //解析完配置文件就立马创建bean对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取Bean对象
        IAccountService as  = (IAccountService)ac.getBean("accountService");
        as.saveAccount();

        //3 手动关闭容器,荣去关闭的同时,bean对象销毁
        ac.close();
    }
/**
 * 账户的业务层实现类
 */
public class AccountServiceImpl implements IAccountService {



    public AccountServiceImpl(){
        System.out.println("对象创建了");
    }

    public void  saveAccount(){
        System.out.println("service中的saveAccount方法执行了。。。");
    }

    public void  init(){
        System.out.println("对象初始化了。。。");
    }
    public void  destroy(){
        System.out.println("对象销毁了。。。");
    }

}

结果(生命周期和容器相同)
对象初始化了。。。
service中的saveAccount方法执行了。。。
对象销毁了

多例对象

   <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"
          scope="prototype" init-method="init" destroy-method="destroy"></bean>

4 spring的依赖注入

spring中的依赖注入

依赖注入:

Dependency Injection

IOC的作用:

降低程序间的耦合(依赖关系)

依赖关系的管理:

以后都交给spring来维护
在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
依赖关系的维护:
就称之为依赖注入。

依赖注入:

能注入的数据:有三类

  • 基本类型和String
  • 其他bean类型(在配置文件中或者注解配置过的bean)
  • 复杂类型/集合类型

注入的方式:有三种

  • 第一种:使用构造函数提供
  • 第二种:使用set方法提供
  • 第三种:使用注解提供

第一种:使用构造函数注入

在这里插入图片描述

构造函数注入:
  • 使用的标签:constructor-arg
  • 标签出现的位置:bean标签的内部
  • 标签中的属性
    • type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数
    • index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
    • name:用于指定给构造函数中指定名称的参数赋值 常用的
      以上三个用于指定给构造函数中哪个参数赋值
    • value:用于提供基本类型和String类型的数据
    • ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:

在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功,实现类对象就一个三个参数的构造方法,必须赋值

弊端:

改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

bean.xml

 <bean id="accountService" class="com.tju.service.impl.AccountServiceImpl">
        <constructor-arg name="name" value="泰斯特"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
        <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>

    <!-- 配置一个日期对象 -->
    <bean id="now" class="java.util.Date"></bean>

实现类对象

public class AccountServiceImpl implements IAccountService {

    //如果是经常变化的数据,并不适用于注入的方式
    private String name;
    private Integer age;
    private Date birthday;

    public AccountServiceImpl(String name,Integer age,Date birthday){
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public void  saveAccount(){
        System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
    }


}

测试获取bean对象

   //1.获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    //2.根据id获取Bean对象
    IAccountService as  = (IAccountService)ac.getBean("accountService");
       as.saveAccount();

结果
service中的saveAccount方法执行了。。。test,18,Apr 26 15:53:14 cst 2019

第二种set方法注入 更常用的方式

  • 涉及的标签:property
  • 出现的位置:bean标签的内部
  • 标签的属性
    • name:用于指定注入时所调用的set方法名称***
    • value:用于提供基本类型和String类型的数据
    • ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:

创建对象时没有明确的限制,可以直接使用默认构造函数

弊端:

如果有某个成员必须有值,则获取对象是有可能set方法没有执行。

bean.xml

<bean id="accountService2" class="com.tju.service.impl.AccountServiceImpl2">
    <property name="name" value="TEST" ></property>
    <property name="age" value="21"></property>
    <property name="birthday" ref="now"></property>
</bean>


<!-- 配置一个日期对象 -->
    <bean id="now" class="java.util.Date"></bean>

实现类对象

public class AccountServiceImpl2 implements IAccountService {

  
    private String name;
    private Integer age;
    private Date birthday;

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public void  saveAccount(){
        System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday);
    }

测试bean对象

  ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取Bean对象


  IAccountService as  = (IAccountService)ac.getBean("accountService2");
  as.saveAccount();

结果
service中的saveAccount方法执行了。。。test,18,Apr 26 15:53:14 cst 2019

关于复杂类型注入,注入集合数据

使用第二种种set方法注入(property使用类的set方法注入)

bean.xml

复杂类型的注入/集合类型的注入
记两组就行

  • 用于给List结构集合注入的标签:
    list array set
  • 用于个Map结构集合注入的标签:
    map props
    结构相同,标签可以互换
 <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3">
        <property name="myStrs">
            <set>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </set>
        </property>

        <property name="myList">
            <array>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </array>
        </property>

        <property name="mySet">
            <list>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </list>
        </property>

        <property name="myMap">
            <props>
                <prop key="testC">ccc</prop>
                <prop key="testD">ddd</prop>
            </props>
        </property>

        <property name="myProps">
            <map>
                <entry key="testA" value="aaa"></entry>
                <entry key="testB">
                    <value>BBB</value>
                </entry>
            </map>
        </property>
    </bean>

实现类

public class AccountServiceImpl3 implements IAccountService {

    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    public void  saveAccount(){
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
        System.out.println(myProps);
    }


}

测试类

  //1.获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");


        IAccountService as  = (IAccountService)ac.getBean("accountService3");
        as.saveAccount();

结果
[AAA, BBB, CCC]
[AAA, BBB, CCC]
[AAA, BBB, CCC]
{testD=ddd, testC=ccc}
{testB=BBB, testA=aaa}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值