工厂模式
把原来分布在各个地方的对象创建的过程都单独抽离出来,统一交给工厂类来负责所需对象的创建
什么是框架?
1.框架本身一般不完整
2.在里面进行填充扩展,迎合公司的业务需求,做公司的项目
3.为了更好的适合大多数项目,不断进行扩展,扩充的东西就是类库
Spring的优势
1.方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给Spring来管理
解耦(代码的某一层发生改变不要影响其他层)
2.方便集成各种优秀的框架
3.方便程序的测试
支持Unit4,可以通过注解测试
4.AOP编程的支持
5.声明式事务的支持
6.降低Java EE API的使用难度
IOC控制反转
指程序开发中,对象的创建不再由程序员来管理和创建,而由spring容器(spring配置文件统一进行控制)来创建和管理,并且spring容器会负责控制对象之间的依赖关系,而不是由程序代码直接控制。因此,控制权由代码转移到spring容器(配置文件),控制权发生了改变。
(IOC控制反转,是一种设计思想,就是将原本程序手动创建对象的控制权交给Ioc容器进行管理,并且ioc容器会负责控制对象之间的依赖关系,这样可以很大程度上简化应用的开发,并将应用从复杂的依赖关系中解脱出来
IOC容器就像一个工厂,当我们需要创建一个对象时,只需要配置好配置文件/注解即可,完全不用考虑对象时如何被创建出来的
IOC的实现原理就是工厂模式+反射机制)
3.举个User小例子
先在main-po里面创建一个User简单实体类,提供无参构造方法
在resource里面右键创建application.xml中写<bean>表示实体类纳入到Spring管理
beans
<beans>:spring配置文件的根标签,在beans中配置自己的对象bean
<bean>:在spring中相当于java中的对象,需要把类配置到容器中
id="":相当于类的对象名,必须保证唯一
class="包名.类名(全限定名)":底层自动使用反射方式,创建该类的对象,并通过id进行标识(不能写接口)
<bean id="user" class="com.jwt.po.User">
把User类纳入到Spring容器中进行管理,当程序运行的时候,在spring容器中,创建一个User对象
调用:
BeanFactory:spring中底层核心接口,提供对象
BeanFactory factory = new ClassPathXmlApplicationContext("application.xml");
User user = (User) factory.getBean("user");
解析:ClassPathXmlApplicationContext()
ClassPath:根路径 resource位置
Xml:读一个后缀是.xml文件
ApplicationContext:读里面的东西,全纳入到spring容器中
new ClassPathXmlApplicationContext(“”)表示读取appication.xml配置文件,spring把里面所有的Bean都创建出来了,通过.getBean()里面的id名确定找哪一个对象(默认情况下,配置文件中所有的Bean都要创建一遍)
getBean("<bean>id名"),有对象就有构造方法,就可以调用无参构造方法
思考题:
BeanFactory factory = new ClassPathXmlApplicationContext("application.xml");
Object person1 = factory.getBean("person1");
Object person2 = factory.getBean("person1");
System.out.println(person1 == person2);
连续创建两次getBean返回同一对象还是新的对象???
同一对象
==判断两对象地址是否一样,如果一样就是同一个对象
总结:控制反转:对象创建的过程交给spring容器来管理
单例模式
单例:在程序的整个运行过程中,该类有且仅有一个对象
查看是不是单例,就看地址是否一样(对象名==对象名)对象名保存的是地址值,看是否相等
scope="singleton" 单例模式(默认值)。
在spring中,加载配置文件的时候,spring容器中只创建一个当前bean对象,无论调用多少次getBean,返回的都是同一个bean对象。
读取配置文件的时候,直接创建该类对象,并且唯一。
scope="prototype" 多例模式。
表示每次调用getBean()方法,都会默认的创建一个新的Bean对象。
读取配置文件的时候,不创建该类对象,只有当每次调用getBean()时,才会创建该类对象
lazy-init="true/false":延迟加载 只有是单例的时候,延迟加载才有意义
true:懒加载,只有当使用的时候才会创建对象
false:不懒加载,读取配置文件立刻创建该类对象
init-method="init":初始化方法
destory-method="destory":销毁方法
applicationContext.getBeanDefinitionCount():有多少Bean
applicationContext.getBeanDefinitionNames():获取容器中所有bean的id的名字
Spring 提供了两种 IoC 容器,分别为 BeanFactory 和 ApplicationContext.
BeanFactory
ApplicationContext
序列化:假设查询到大量数据,内存放不下,可临时固化到硬盘中,io流读取到硬盘中,不再那么大的时候,通过输入流返回给用户
Spring中创建Bean对象的常用方式
1.使用构造方法来创建对象
在bean里面,<constructor-arg name="属性名" value="赋值">
<constructor-arg index="下标名" value="赋值">
2.使用静态工厂来创建对象
创建一个factory包,里面写一个静态方法调用User
先找到工厂类,再找到工厂类里面的方法来创建对象
<bean id="对象名" class="工厂包.类名" factory-method="静态方法名"></bean>
<bean id="user5" class="com.jwt.spring.factory01.Fac" factory-method="getInstance"></bean>
3.使用实例工厂方法来创建对象
实例方法创建对象
3.1创建实例工厂
<bean id="factory对象名" class="工厂包.类名"></bean>
3.2指定工厂方法
<bean id="对象名" factory-bean="factory对象名" factory-method="方法名"></bean>
依赖注入(DI注入)
组件(Bean)之间的依赖关系由容器在运行的时候来决定
容器动态的将依赖的组件注入到对应的bean中
解耦,对象间的依赖关系不再由程序员维护,全由配置文件来维护
源代码部分尽量少修改
1.set方法注入(跟set方法名绑定)
写dao,service实例
service实现类中写privite UserDao userDao;写set方法;
在application.xml中写
<bean id="userDao dao接口" class="com.jwt.dao.UserDaoImpl dao实现类"></bean>
<bean id="userService" class="com.jwt.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
property中name写set方法名set后面首字母小写,ref写当前关联的bean id名(Dao中id名)
测试:
ApplicationContext factory = new ClassPathXmlApplicationContext("application.xml");
UserService userService = (UserService) factory.getBean("userService");
userService.addUser();
2.构造方法注入
同上,set方法换构造方法
在application.xml中写
<bean id="userDao" class="com.jwt.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.jwt.service.UserServiceImpl">
<!-- <property name="userDao" ref="userDao"></property>-->
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
constructor中name写构造方法参数名,ref写当前关联的bean id名(Dao中id名)
假设一个案例:需要换数据库
如果修改数据库,只需要重写dao层即可
之前方法:在serviceImpl中写不同的实现类
DI注入:不需要改业务层代码,只需要在配置文件中修改依赖关系
3.自动注入
配置文件中设置autowire,为引入属性进行隐式自动注入
byName:根据名称自动注入(bean中id名与private dao)
byType:根据类型自动注入(可能有多个)