Spring入门

Spring的优势

  • 方便解耦,简化开发。通过IoC容器,将对象间的依赖关系交给Spring控制
  • 支持AOP编程。方便进行面向切面的编程。
  • 事务式编程,通过声明的方式进行事务的管理。
  • 方便程序测试,非容器依赖的编程方式。
  • 集成各种优秀框架

IoC的概念及作用

控制反转 Inversion of Control

  • 三层对象存储在Map中,这个Map被称之为容器
  • 工厂负责从容器中获取指定对象的类。过去是主动获取new,现在是被动,获取对象的同时跟工厂要,工厂为我们创建或查找对象。

这种被动接受的方式获取对象的思想就是控制反转,是spring框架的核心之一

Spring入门案例

创建业务层接口和实现类

/** 
 * 账户的业务层接口    *
 *  public interface IAccountService {  /** 
  * 保存账户(此处只是模拟,并不是真的要保存)   */  
  void saveAccount(); } 
 
/** 
 * 账户的业务层实现类  * 
 public class AccountServiceImpl implements IAccountService { 
 private IAccountDao
 accountDao = new AccountDaoImpl();//此处的依赖关系有待解决 
 
 @Override  public void saveAccount() {  
 accountDao.saveAccount(); 
 } } 

创建持久层接口和实现类

/** 
 * 账户的持久层接口  *
  public interface IAccountDao { 
   /** * 保存账户   */ 
    void saveAccount(); } 
 
/** 
 * 账户的持久层实现类  *
  public class AccountDaoImpl implements IAccountDao { 
   @Override  public void saveAccount() {   
   System.out.println("保存了账户");
    } 
}

基于XML的配置

拷贝jar包到lib目录

在这里插入图片描述

在类的根路径下创建XML文件

在这里插入图片描述
为配置文件导入约束

/spring-framework-5.0.2.RELEASE/docs/spring-framework-reference/html5/core.html 

让spring管理资源,在配置文件中配置service和dao

<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中       id 属性:对象的唯一标识。       class 属性:指定要创建对象的全限定类名 --> 
<!-- 配置 service -->    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean> 
<!-- 配置 dao --> <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean> 

测试配置是否成功

public static void main(String[] args) {   
//1.使用 ApplicationContext 接口,就是在获取 spring 容器   
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");   
//2.根据 bean 的 id 获取对象 
  IAccountService aService = (IAccountService) ac.getBean("accountService");   
  System.out.println(aService);   
  IAccountDao aDao = (IAccountDao) ac.getBean("accountDao");   
  System.out.println(aDao);  } } 

Spring基于XML的IOC细节

Spring中工厂的类结构图

在这里插入图片描述
在这里插入图片描述

BeanFactory和ApplicatoinContext的区别

  • BeanFactory是Spring容器中的顶层接口,ApplicatoinContext是它的子接口,
  • 区别:创建对象的时间点不一样
  • ApplicatoinContext:只要一读取配置文件就会创建对象
  • BeanFactory:使用时创建对象

ApplicatoinContext接口的实现类

  • ClassPathXmlApplicationContext: 从类的根路径下加载配置文件(推荐使用)
  • FileSystemXmlApplicationContext:从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
  • AnnotationConfigApplicationContext: 当使用注解配置容器对象时,需要使用此类来创建spring容器。用来读取注解

IOC中bean标签和管理对象

bean标签

用于配置对象让Spring来创建,默认情况下调用的时类中的无参构造函数,如果没有无参构造函数则不能创建成功。
id: 给对象在容器中提供一个唯一标识用于获取对象
class:指定类的全限定类名,用于反射创建对象,默认情况下调用无参构造函数
scope:指定对象的作用范围

  • singleton :默认值,单例的. * prototype :多例的.

bean的作用范围和生命周期

单例对象:scope=“singleton”

  • 一个应用只有一个对象的实例,它的作用范围是整个引用。
  • 生命周期
      • 对象出生:当应用加载,常见容器时,对象就被创建了
      • 对象生存:只要容器在
      • 对象死亡:应用卸载,销毁容器时,对象就被销毁

多例对象: scope=“prototype”

  • 每次访问对象时,都会重新创建对象实例
  • -生命周期
      • 对象出生:当使用对象时,创建新的对象实例。
      • 对象生存: 只要对象在使用
      • 对象死亡: 当对象长时间不用时

实例化Bean的三种方式

使用默认无参构造函数

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/> 

spring管理静态工厂-使用静态工厂的方法创建对象

/** 
 * 模拟一个静态工厂,创建业务层实现类  */ 
 public class StaticFactory {  
  public static IAccountService createAccountService(){   
  return new AccountServiceImpl();  }
   } 
<!-- 此种方式是:   **使用 StaticFactory 类中的静态方法 createAccountService 创建对象**,并存入 spring 容器   id 属性:指定 bean 的 id,用于从容器中获取   class 属性:指定静态工厂的全限定类名   factory-method 属性:指定生产对象的静态方法  --> <bean id="accountService"  
   class="com.itheima.factory.StaticFactory"     factory-method="createAccountService"></bean> 

spring管理实例工厂-使用实例工厂的方法创建对象

/** 
 * 模拟一个实例工厂,创建业务层实现类  * 此工厂创建对象,必须现有工厂实例对象,再调用方法  */ 
 public class InstanceFactory {   
 public IAccountService createAccountService(){   
 return new AccountServiceImpl();  
 } 
 } 
 <!-- 此种方式是:    先把工厂的创建交给 spring 来管理。   然后在使用工厂的 bean 来调用里面的方法   factory-bean 属性:用于指定实例工厂 bean 的 id。   factory-method 属性:用于指定实例工厂中创建对象的方法。  --> 
 <bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean> 
  <bean id="accountService"      factory-bean="instancFactory"      factory-method="createAccountService"></bean> 

Spring的依赖注入

概念

  • 依赖注入: Dependency Injection。是spring框架核心ioc的具体实现。
  • 我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。 简单的说,就是等框架把持久层对象传入业务层,而不用我们自己去获取。

构造函数注入

  • 就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让 spring 框架来为我们注入。
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; 
  } 
 
 @Override  public void saveAccount() {  
  System.out.println(name+","+age+","+birthday);  
   } 
   }
  
  • 使用构造函数的方式,给 service 中的属性传值 要求: 类中需要提供一个对应参数列表的构造函数。
  • 涉及的标签: constructor-arg
  • 属性: index:指定参数在构造函数参数列表的索引位置 type:指定参数在构造函数中的数据类型 name:指定参数在构造函数中的名称 用这个找给谁赋值
    上面三个都是找给谁赋值,下面两个指的是赋什么值的========
    value:它能赋的值是基本数据类型和 String 类型 ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
<bean id="accountService" class="com.itheima.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> 

set方法注入

  • 在类中提供需要注入成员的set方法
public class AccountServiceImpl 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;  } 
 
 @Override  public void saveAccount() {   
 System.out.println(name+","+age+","+birthday);   } 
 } 
  • 通过配置文件给 bean 中的属性传值:使用 set 方法的方式 涉及的标签: property
  • 属性:
  • name:找的是类中 set 方法后面的部分 ref:给属性赋值是其他 bean 类型的 value:给属性赋值是基本数据类型和 string 类型
  • 实际开发中,此种方式用的较多。
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">   
<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>

注入集合属性

  • 给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。 我们这里介绍注入数组List,Set,Map,Properties
public class AccountServiceImpl 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;  } 
 
 @Override  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);  
  	}
   }
<!-- 注入集合数据    List 结构的:   array,list,set 
                            Map 结构的   map,entry,props,prop 
--> 
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 
 <!-- 在注入集合数据时,只要结构相同,标签可以互换 -->
  <!-- 给数组注入数据 -->  
  <property name="myStrs"> 
  <set>    
  <value>AAA</value>    
  <value>BBB</value>    
  <value>CCC</value>  
   </set> 
 </property> 
 <!-- 注入 list 集合数据 -->  
 <property name="myList">  
  <array>    
  <value>AAA</value>    
  <value>BBB</value>   
   <value>CCC</value>   
   </array>  
   </property> 
 <!-- 注入 set 集合数据 -->  
 <property name="mySet"> 
  <list>    
  <value>AAA</value>    
  <value>BBB</value>    
  <value>CCC</value>  
   </list>  
   </property> 
 <!-- 注入 Map 数据 -->  
 <property name="myMap">   
 <props> 
   <prop key="testA">aaa</prop>   
   <prop key="testB">bbb</prop>   
  </props> 
 </property> 
 <!-- 注入 properties 数据 --> 
 <property name="myProps"> 
 <map>   
  <entry key="testA" value="aaa"></entry> 
   <entry key="testB">    <value>bbb</value> </entry>  
    </map>
     </property> 
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值