Inversion of Control,缩写为IoC,把创建对象的权利交给框架,是框架的重要特征,它包括依赖注入和依赖查找.
总结
/** -------------总结---------------------------- * AccountServiceImpl as = new AccountServiceImpl(); * AccountServiceImpl as = (AccountServiceImpl) BeanFactory.getBean("accountService"); * 这是两种截然不同的创建对象的方式 * 第一种 是 new app就是直接主动去找资源 * 第二种是app通过联系工厂 去找资源 ,工厂去控制资源,并且工厂为app提供资源 *而这就是IOC思想(控制反转) */Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
配置文件
bean.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"> <!-- 把对象的创建交给spring来管理--> <bean id= "accountService" class= "x.xss.service.impl.AccountServiceImpl"></bean> <bean id="accountDao" class="x.xss.dao.impl.AccountDaoImpl"></bean> </beans>表现层
/** * 模拟一个表现层,用于调用业务层 */ public class Client { /** * 获取spring的Ioc容器,并根据id获取对象 * * ApplicationContext的三个常用实现类: * * ClassPathXmlApplicationContext : 它可以加载类路径下的配置文件, * 要求配置文件必须在类路径下。 * 不在的话,加载不了。也就无法获 * 取核心容器对象 * * FileSystemXmlApplicationContext : 它可以加载磁盘任意路径下的配置文件 * (必须有访问权限) * AnnotationConfigApplicationContext : 它是用于读取注解创建容器的。 * * 核心容器的两个接口引发的问题 bean对象的创建默认是单例的 * 1, ApplicationContext: 单例对象适应 (实际开发中更多使用此接口) * 它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。 * 也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。 * *,2, BeanFactory; 多例对象适用 * 它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。 * 也就是说,什么时候根据id获取对象了,就什么时候才创建真正的对象。 * * * @param args */ public static void main(String[] args) { //1,获取核心容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); //ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\2019\\IdeaProjects\\day722_03spring\\src\\main\\resources\\bean.xml"); //2,根据id获取Bean对象 //两种方式 ,强转,或者是输入字节码文件强转 AccountService as = (AccountService) ac.getBean("accountService"); AccountDao adao = ac.getBean("accountDao", AccountDao.class); System.out.println(as); System.out.println(adao); // as.saveAccount(); /* //------- BeanFactory 创建对象,创建的bean是多例的---------- Resource resource = new ClassPathResource("bean.xml"); BeanFactory factory = new XmlBeanFactory(resource); AccountService as = (AccountService)factory.getBean("accountService"); System.out.println(as); */ } } BeanFactory 才是 Spring 容器中的顶层接口。 ApplicationContext 是它的子接口。 BeanFactory 和 ApplicationContext 的区别: 创建对象的时间点不一样。 ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。 BeanFactory:什么使用什么时候创建对象。
ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件 推荐使用这种 FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。
作用:
用于配置对象让 spring 来创建的。
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性:
id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
singleton :默认值,单例的.
prototype :多例的.
request : WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
session : WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么 globalSession 相当于 session.
init-method:指定类中的初始化方法名称。
destroy-method:指定类中销毁方法名称。
在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性标签时。 采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建
/*配置文件中 */ <bean id= "accountService" class= "x.xss.service.impl.AccountServiceImpl"></bean> //实现类中 public class AccountServiceImpl implements AccountService { //默认构造函数 public AccountServiceImpl() { System.out.println("对象被创建了"); } } 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
/** * 模拟一个工厂类(此类可能存在于jar包中, * 我们无法通过修改源码的方式来提供默认构造函数 */ public class InstanceFactory { public AccountService getAccountServive(){ return new AccountServiceImpl(); } } <!-- 此种方式是: 先把工厂的创建交给 spring 来管理。 然后在使用工厂的 bean 来调用里面的方法 factory-bean 属性:用于指定实例工厂 bean 的 id。 factory-method 属性:用于指定实例工厂中创建对象的方法。 --> <bean id="instanceFactory" class="x.xss.factory.InstanceFactory"></bean> <!--accountService的创建不再自己创建了,而是去使用 nstanceFactory,所以加上下面的配置--> <bean id="accountService" factory-bean="instanceFactory" <--找到此类中的--> factory-method="getAccountServive"> <--此方法--> </bean> 使用工厂中的静态方式创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
/** * 模拟一个工厂类(此类可能存在于jar包中, * 我们无法通过修改源码的方式来提供默认构造函数 * 这里是静态的方法 */ public class StaticFactory { public static AccountService getAccountServive(){ return new AccountServiceImpl(); } } <!--使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器 id 属性:指定 bean 的 id,用于从容器中获取 class 属性:指定静态工厂的全限定类名 factory-method 属性:指定生产对象的静态方法--> <bean id="accountService" class="x.xss.factory.StaticFactory" factory-method="getAccountServive"> </bean>默认是单例的 bean标签的scope属性; 作用: 用于指定bean的作用范围 取值: singleton : 单例的(也是默认值)(常用) prototype : 多例的 (常用) request : 作用于web应用的 请求 范围 session : 作用于web应用的 会话 范围 global-session: 作用于 集群环境的会话范围(全局会话范围) ,当不是集群环境时,就是session
<bean id= "accountService" class= "x.xss.service.impl.AccountServiceImpl" scope="singleton" init-method="init" destroy-method="destory"></bean>单例对象 出生 容器创建时,对象出生 活着 死亡 容器销毁时,对象消亡 总结:单例对象的生命周期与容器相同 多例对象 出生 当使用对象时,spring框架会创建 活着 对象在使用过程中 bean就一直存在 死亡 当对象长时间不用,且没有别的对象引用时, ·有java的垃圾回收器回收
依赖注入: 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对象的实例化方式,使我们在创建对象时,如果用不到这些数据, 也还是要提供。
<bean id= "accountService" class= "x.xss.service.impl.AccountServiceImpl"> <constructor-arg name="aaa" value="小明"></constructor-arg> <constructor-arg name="bbb" value="18"></constructor-arg> <constructor-arg name="ccc" ref="now"></constructor-arg> </bean> <!--配置一个日期对象--> <bean id="now" class="java.util.Date"></bean> /** * 账户的业务层实现类 */ public class AccountServiceImpl implements AccountService { //如果是经常变化的数据,并不适用于注入的方式 private String aaa; private Integer bbb; private Date ccc; //构造方法 public AccountServiceImpl(String aaa, Integer bbb, Date ccc) { this.aaa = aaa; this.bbb = bbb; this.ccc = ccc; } public void saveAccount() { System.out.println("service中的saveAccount方法被执行了..."+ aaa + "," + bbb + "," + ccc); } } 涉及的标签:property 出现的位置:bean标签的内部 标签的属性 name:用于指定注入时所调用的set方法名称 value:用于提供基本类型和String类型的数据 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 优势: 创建对象时没有明确的限制,可以直接使用默认构造函数 弊端: 如果有某个成员必须有值,则获取对象时有可能set方法没有执行。
<bean id= "accountService2" class= "x.xss.service.impl.AccountServiceImpl2"> <property name="aaa" value="小红"></property> <property name="bbb" value="15"></property> <property name="ccc" ref="now"></property> </bean> /** * 账户的业务层实现类 */ public class AccountServiceImpl2 implements AccountService { //如果是经常变化的数据,并不适用于注入的方式 private String aaa; private Integer bbb; private Date ccc; //set方法 public void setAaa(String aaa) { this.aaa = aaa; } public void setBbb(Integer bbb) { this.bbb = bbb; } public void setCcc(Date ccc) { this.ccc = ccc; } public void saveAccount() { System.out.println("service中的saveAccount方法被执行了..."+ aaa + "," + bbb + "," + ccc); } } 用于给List结构集合注入的标签: list array set 用于个Map结构集合注入的标签: map props 结构相同,标签可以互换
<bean id="accountService3" class="x.xss.service.impl.AccountServiceImpl3"> <property name="a"> <set> <value>数组1</value> <value>数组2</value> <value>数组3</value> </set> </property> <property name="b"> <array> <value>List1</value> <value>List2</value> <value>List3</value> </array> </property> <property name="c"> <set> <value>Set1</value> <value>Set2</value> <value>Set3</value> </set> </property> <property name="d"> <props> <prop key="map1">m111</prop> <prop key="map2">m222</prop> </props> </property> <property name="e"> <map> <entry key="写法1" value="Properties1111"></entry> <entry key="写法2"> <value>Properties2222</value> </entry> </map> </property> </bean> /** * 账户的业务层实现类 */ public class AccountServiceImpl3 implements AccountService { private String[] a; private List<String> b; private Set<String> c; private Map<String,String>d; private Properties e; //set 方法 public void setA(String[] a) { this.a = a; } public void setB(List<String> b) { this.b = b; } public void setC(Set<String> c) { this.c = c; } public void setD(Map<String, String> d) { this.d = d; } public void setE(Properties e) { this.e = e; } public void saveAccount() { System.out.println(Arrays.toString(a)); System.out.println(b); System.out.println(c); System.out.println(d); System.out.println(e); } } g,String>d; private Properties e; //set 方法 public void setA(String[] a) { this.a = a; } public void setB(List<String> b) { this.b = b; } public void setC(Set<String> c) { this.c = c; } public void setD(Map<String, String> d) { this.d = d; } public void setE(Properties e) { this.e = e; } public void saveAccount() { System.out.println(Arrays.toString(a)); System.out.println(b); System.out.println(c); System.out.println(d); System.out.println(e); } }