1、Spring是什么 Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。 2、IoC控制反转是什么 控制反转(Inverse Of Control,简写为IoC)把创建对象的权利交给框架,是框架的重要特征,并非面向对象编程的专用术语。它包括依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。 IoC的作用:消减计算机的耦合(解除我们代码中的依赖关系)。
2.1、工厂模式解耦,简化开发 通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。 程序耦合关系:即程序之间的依赖关系,包括类之间的依赖,方法之间的依赖。 解耦:降低程序之间的依赖关系。实际开发中应该做到,编译期不依赖,运行时才依赖。 解耦思路:
- 通过读取配置文件来获取要创建的对象全限定类名;
- 使用反射来创建对象,而避免使用new关键字;
2.2、代码地址
重点代码:BeanFactory
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.george.factory; 2 3 /** 4 * @author :zhangrr 5 * @date :Created in 2023/5/28 15:52 6 * @description: 7 * @modified By: 8 * @version: 9 */ 10 11 import java.io.InputStream; 12 import java.util.Enumeration; 13 import java.util.HashMap; 14 import java.util.Map; 15 import java.util.Properties; 16 17 /** 18 * 一个创建Bean对象的工厂 19 * 20 * Bean:在计算机英语中,有可重用组件的含义。 21 * JavaBean:用java语言编写的可重用组件。 22 * javabean > 实体类 23 * 24 * 它就是创建我们的service和dao对象的。 25 * 26 * 第一个:需要一个配置文件来配置我们的service和dao 27 * 配置的内容:唯一标识=全限定类名(key=value) 28 * 第二个:通过读取配置文件中配置的内容,反射创建对象 29 * 30 * 我的配置文件可以是xml也可以是properties 31 */ 32 public class BeanFactory { 33 //定义一个Properties对象 34 private static Properties props; 35 36 //定义一个Map,用于存放我们要创建的对象。我们把它称之为容器 37 private static Map<String,Object> beans; 38 39 //使用静态代码块为Properties对象赋值 40 static { 41 try { 42 //实例化对象 43 props = new Properties(); 44 //获取properties文件的流对象 45 InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"); 46 props.load(in); 47 //实例化容器 48 beans = new HashMap<String,Object>(); 49 //取出配置文件中所有的Key 50 Enumeration keys = props.keys(); 51 //遍历枚举 52 while (keys.hasMoreElements()){ 53 //取出每个Key 54 String key = keys.nextElement().toString(); 55 //根据key获取value 56 String beanPath = props.getProperty(key); 57 //反射创建对象 58 Object value = Class.forName(beanPath).newInstance(); 59 //把key和value存入容器中 60 beans.put(key,value); 61 } 62 }catch(Exception e){ 63 throw new ExceptionInInitializerError("初始化properties失败!"); 64 } 65 } 66 67 /** 68 * 根据bean的名称获取对象 69 * @param beanName 70 * @return 71 */ 72 public static Object getBean(String beanName){ 73 // String beanPath = props.getProperty(beanName); 74 // System.out.println(beanPath); 75 return beans.get(beanName); 76 } 77 78 /** 79 * 根据Bean的名称获取bean对象 80 * @param beanName 81 * @return 82 83 public static Object getBean(String beanName){ 84 Object bean = null; 85 try { 86 String beanPath = props.getProperty(beanName); 87 // System.out.println(beanPath); 88 bean = Class.forName(beanPath).newInstance();//每次都会调用默认构造函数创建对象 89 }catch (Exception e){ 90 e.printStackTrace(); 91 } 92 return bean; 93 }*/ 94 }View Code
调用示例:
UserServices ias = (UserServices) BeanFactory.getBean("userService");
ias.saveuser();
3、Spring框架中的IoC
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
bean.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <!--把对象的创建交给spring来管理--> 8 <!--spring对bean的管理细节 9 1.创建bean的三种方式 10 2.bean对象的作用范围 11 3.bean对象的生命周期 12 --> 13 14 <!--创建Bean的三种方式 --> 15 <!-- 第一种方式:使用默认构造函数创建。 16 在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。 17 采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建。 18 --> 19 <bean id="accountService" class="com.george.services.impl.UserServicesImpl"></bean> 20 21 22 <!-- 第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器) 23 24 <bean id="instanceFactory" class="com.george.factory.InstanceFactory"></bean> 25 <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean> 26 --> 27 28 29 <!-- 第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器) 30 31 32 <bean id="accountService" class="com.george.factory.StaticFactory" factory-method="getAccountService"></bean> 33 --> 34 35 36 <!-- bean的作用范围调整 37 bean标签的scope属性: 38 作用:用于指定bean的作用范围 39 取值: 常用的就是单例的和多例的 40 singleton:单例的(默认值) 41 prototype:多例的 42 request:作用于web应用的请求范围 43 session:作用于web应用的会话范围 44 global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session 45 46 <bean id="accountService" class="com.george.services.impl.UserServicesImpl" scope="prototype"></bean> 47 --> 48 49 <!-- bean对象的生命周期 50 单例对象 51 出生:当容器创建时对象出生 52 活着:只要容器还在,对象一直活着 53 死亡:容器销毁,对象消亡 54 总结:单例对象的生命周期和容器相同 55 多例对象 56 出生:当我们使用对象时spring框架为我们创建 57 活着:对象只要是在使用过程中就一直活着。 58 死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收 59 60 <bean id="accountService" class="com.george.services.impl.UserServicesImpl" 61 scope="prototype" init-method="init" destroy-method="destroy"></bean> 62 --> 63 </beans>View Code
InstanceFactory:
public class InstanceFactory {
public UserServices getAccountService(){
return new UserServicesImpl();
}
}
StaticFactory:
public class StaticFactory {
public static UserServices getAccountService(){
return new UserServicesImpl();
}
}
UserServicesImpl:
public class UserServicesImpl implements UserServices {
public UserServicesImpl(){
System.out.println("对象创建了");
}
public void saveUser(){
System.out.println("service中的saveAccount方法执行了。。。");
}
public void init(){
System.out.println("对象初始化了。。。");
}
public void destroy(){
System.out.println("对象销毁了。。。");
}
}
client:
public class client {
public static void main(String[] args) {
//1.获取核心容器对象
// ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//2.根据id获取Bean对象
UserServices as = (UserServices)ac.getBean("accountService");
as.saveUser();
//手动关闭容器
ac.close();
}
}
4、Spring依赖注入
<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>
解析“配置一个日期对象”
Spring通过class读取全限定类名,反射创建一个对象,存入Spring容器,通过id 取出来,应用在birthday参数赋值上
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 AccountServiceImpl : 2 public class AccountServiceImpl implements IAccountService { 3 4 //如果是经常变化的数据,并不适用于注入的方式 5 private String name; 6 private Integer age; 7 private Date birthday; 8 9 public AccountServiceImpl(String name,Integer age,Date birthday){ 10 this.name = name; 11 this.age = age; 12 this.birthday = birthday; 13 } 14 15 public void saveAccount(){ 16 System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday); 17 } 18 19 20 } 21 22 23 bean.xml 24 25 <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 26 <constructor-arg name="name" value="泰斯特"></constructor-arg> 27 <constructor-arg name="age" value="18"></constructor-arg> 28 <constructor-arg name="birthday" ref="now"></constructor-arg> 29 </bean> 30 31 <!-- 配置一个日期对象 --> 32 <bean id="now" class="java.util.Date"></bean>View Code
注解实现类的代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class AccountServiceImpl implements IAccountService { 2 3 //如果是经常变化的数据,并不适用于注入的方式 4 private String name; 5 private Integer age; 6 private Date birthday; 7 8 public AccountServiceImpl(String name,Integer age,Date birthday){ 9 this.name = name; 10 this.age = age; 11 this.birthday = birthday; 12 } 13 14 public void saveAccount(){ 15 System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday); 16 } 17 18 19 } 20 21 22 23 24 25 public class AccountServiceImpl2 implements IAccountService { 26 27 //如果是经常变化的数据,并不适用于注入的方式 28 private String name; 29 private Integer age; 30 private Date birthday; 31 32 public void setName(String name) { 33 this.name = name; 34 } 35 36 public void setAge(Integer age) { 37 this.age = age; 38 } 39 40 public void setBirthday(Date birthday) { 41 this.birthday = birthday; 42 } 43 44 public void saveAccount(){ 45 System.out.println("service中的saveAccount方法执行了。。。"+name+","+age+","+birthday); 46 } 47 48 49 } 50 51 52 53 54 55 56 public class AccountServiceImpl3 implements IAccountService { 57 58 private String[] myStrs; 59 private List<String> myList; 60 private Set<String> mySet; 61 private Map<String,String> myMap; 62 private Properties myProps; 63 64 public void setMyStrs(String[] myStrs) { 65 this.myStrs = myStrs; 66 } 67 68 public void setMyList(List<String> myList) { 69 this.myList = myList; 70 } 71 72 public void setMySet(Set<String> mySet) { 73 this.mySet = mySet; 74 } 75 76 public void setMyMap(Map<String, String> myMap) { 77 this.myMap = myMap; 78 } 79 80 public void setMyProps(Properties myProps) { 81 this.myProps = myProps; 82 } 83 84 public void saveAccount(){ 85 System.out.println(Arrays.toString(myStrs)); 86 System.out.println(myList); 87 System.out.println(mySet); 88 System.out.println(myMap); 89 System.out.println(myProps); 90 } 91 92 93 }View Code
bean.xml的代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <!-- spring中的依赖注入 8 依赖注入: 9 Dependency Injection 10 IOC的作用: 11 降低程序间的耦合(依赖关系) 12 依赖关系的管理: 13 以后都交给spring来维护 14 在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明 15 依赖关系的维护: 16 就称之为依赖注入。 17 依赖注入: 18 能注入的数据:有三类 19 基本类型和String 20 其他bean类型(在配置文件中或者注解配置过的bean) 21 复杂类型/集合类型 22 注入的方式:有三种 23 第一种:使用构造函数提供 24 第二种:使用set方法提供 25 第三种:使用注解提供(明天的内容) 26 --> 27 28 29 <!--构造函数注入: 30 使用的标签:constructor-arg 31 标签出现的位置:bean标签的内部 32 标签中的属性 33 type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型 34 index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始 35 name:用于指定给构造函数中指定名称的参数赋值 常用的 36 =============以上三个用于指定给构造函数中哪个参数赋值=============================== 37 value:用于提供基本类型和String类型的数据 38 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 39 40 优势: 41 在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。 42 弊端: 43 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。 44 --> 45 <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> 46 <constructor-arg name="name" value="泰斯特"></constructor-arg> 47 <constructor-arg name="age" value="18"></constructor-arg> 48 <constructor-arg name="birthday" ref="now"></constructor-arg> 49 </bean> 50 51 <!-- 配置一个日期对象 --> 52 <bean id="now" class="java.util.Date"></bean> 53 54 55 56 <!-- set方法注入 更常用的方式 57 涉及的标签:property 58 出现的位置:bean标签的内部 59 标签的属性 60 name:用于指定注入时所调用的set方法名称 61 value:用于提供基本类型和String类型的数据 62 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 63 优势: 64 创建对象时没有明确的限制,可以直接使用默认构造函数 65 弊端: 66 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。 67 --> 68 <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2"> 69 <property name="name" value="TEST" ></property> 70 <property name="age" value="21"></property> 71 <property name="birthday" ref="now"></property> 72 </bean> 73 74 75 <!-- 复杂类型的注入/集合类型的注入 76 用于给List结构集合注入的标签: 77 list array set 78 用于个Map结构集合注入的标签: 79 map props 80 结构相同,标签可以互换 81 --> 82 <bean id="accountService3" class="com.itheima.service.impl.AccountServiceImpl3"> 83 <property name="myStrs"> 84 <set> 85 <value>AAA</value> 86 <value>BBB</value> 87 <value>CCC</value> 88 </set> 89 </property> 90 91 <property name="myList"> 92 <array> 93 <value>AAA</value> 94 <value>BBB</value> 95 <value>CCC</value> 96 </array> 97 </property> 98 99 <property name="mySet"> 100 <list> 101 <value>AAA</value> 102 <value>BBB</value> 103 <value>CCC</value> 104 </list> 105 </property> 106 107 <property name="myMap"> 108 <props> 109 <prop key="testC">ccc</prop> 110 <prop key="testD">ddd</prop> 111 </props> 112 </property> 113 114 <property name="myProps"> 115 <map> 116 <entry key="testA" value="aaa"></entry> 117 <entry key="testB"> 118 <value>BBB</value> 119 </entry> 120 </map> 121 </property> 122 </bean> 123 124 125 126 127 128 129 130 131 132 133 134 </beans>View Code
调用代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args) { 2 //1.获取核心容器对象 3 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); 4 //2.根据id获取Bean对象 5 // IAccountService as = (IAccountService)ac.getBean("accountService"); 6 // as.saveAccount(); 7 8 // IAccountService as = (IAccountService)ac.getBean("accountService2"); 9 // as.saveAccount(); 10 11 IAccountService as = (IAccountService)ac.getBean("accountService3"); 12 as.saveAccount(); 13 14 }View Code 标签:String,void,private,name,birthday,public,Spring5 From: https://www.cnblogs.com/Nlife/p/17438788.html