Spring 框架优点:
动态解耦 方便测试 降低java ee API的难度 方便集成各种框架
支持AOP 声明式事务的支持 自定义功能模块
三层架构:
dao层 数据访问层/数据交互层 与数据库进行增删改查操作
service层 业务逻辑层 处理业务逻辑,如登录的判断
web层 表现层/用户访问层 接收请求,反馈(页面/数据)
IOC:控制反转 容器 IOC容器
负责管理各种对象的生命周期
DI:依赖注入
属性注入:
set方式的注入:
普通属性--》必须具备set方法,空参构造器
集合属性--》
List
<list>
<value></value>
</list>
构造器注入(无参构造器进行反射)
工厂类
实现factoryBean接口
实例工厂类对象
静态工厂
自动注入(自动注入类与类之间的关联关系)
Spring管理对象所声明的生命周期
自定义属性编辑器
自定义事件
注解
出现全限定类名:反射
创建对象:new
spring的容器
去配置属性(property)的注入
如何去配置 set类的注入
pojo类
是一个简单的java类,用来反映实体的属性
数据
web网页:json格式的字符串或者数组
{
key1:value1,
key2:value2
}
java用一个类来描述数据
gender boolean true "男"
javaBean -->组件
AOP:面向切面编程
宗旨:简化操作 降低耦合
springframework web date aop test core
核心:core aop
三层架构
web层 接收数据
service 业务处理
dao 和数据库交互
Spring帮助创建对象
将原本写死的代码,分开,再在运行期间,动态的将各部分代码结合在一起
将类和类之间的关联关系进行处理
Spring:轻量级框架
容器:1.GUI 2web容器 3Spring容器
Spring 的ioc和aop功能(面试重点)
Spring功能:
1.帮助程序员管理了对象的生命周期
2.attribute对应的属性,property对应的参数
Spring:配置文件--xml
1.Spring中如何帮助我们管理对象?
将要管理的对象,交给(配置)Spring容器
2.如何将对象配置给Spring容器
3,哪些对象可以配置给
4.配置到容器中的类对象叫什么
bean对象
5.配置进去后,有什么好处
反复使用
可以理解为我们帮项目找了一个管家
1.管理类对象的生命周期
2.将建立对象和对象之前的复杂关联关系
3.动态的结合代码
将主动变被动
BeanFactory接口
getBean(string name)
IOC核心容器:
核心:让Spring容器知道谁是工厂类
ioc:
//1 声明要读取的xml文件路径(如果有多个可以放在数组中)
//2 读取xml文件创建spring的容器contanier
//3 从容器container中根据配置的名字拿出需要使用的对象
//4 使用对象进行操作(对象中的需要的各种数据和依赖的其他对象早已经被spring的容器注入进来)
[1]set注入(当前这个类一定要有对应的set方法)
1.可以帮助我们管理对象的生命周期
2.可以构建对象和对象之间的关联关系
value字符串 ref引用对应的bean对象
applicationContext接口 继承了BeanFactory接口
[2]给对象中注入集合
list set
map <entry key ="" value=""/>
prop <prop key="p1">a</prop>
[3]构造器注入
xml文件中有bean的配置,而且bean对应的java文件中有无参构造器通过反射调用无参构造器
1.根据参数类型 与bean中参数位置无关
问题:参数类型相同时无法区分
构造器重载时无法区分(不会报错)
2.根据参数位置的下标(从0开始)
<bean name="student" class="com.briup.bean.Student">
<constructor-arg index="0" value="2" ></constructor-arg>
<constructor-arg index="1" value="xioawu" ></constructor-arg>
<constructor-arg index="2" value="20" ></constructor-arg>
</bean>
因为构造器中参数的位置,可能会造成数据错误
<bean name="student" class="com.briup.bean.Student">
<constructor-arg index="0" value="2" name="id" ></constructor-arg>
<constructor-arg index="1" value="xioawu" name="name" ></constructor-arg>
<constructor-arg index="2" value="20" name="age" ></constructor-arg>
</bean>
构造器重载:加个name
(一般用构造器注入)
[4]自动注入 auowire
自动建立类与类之间的关联关系
autowire="byName":找set方法中同名的bean
spring容器会到当前的类中找property的名字,然后
再根据这个名字去spring容器中找有没有和这个property
名字相同的对象,有的话,就把这个对象当做参数放到
setXxxx这个方法里面注入进来.
autowire="byType" 根据bean对象的类型进行匹配,bean需要唯一 找到多个,报错
spring容器会根据当前类中的set方法里面参数的类型,
去容器中找相匹配的对象,如果没找到就算了,如果找到
一个就注入进来,如果找到多个,那么就会报错了.
在根标签中指定 default-autowire="byName" bean中不用再配置byName
局部配置覆盖全局配置
[5]继承
原来类与类的继承 耦合太高
保存父类原有的方法的同时添加一些新方法
<bean name="tSon" parent="teacher">
//表示创建一个类,tSon,为teacher bean的子类
注意:调用tSon时,tSon为父类型的
Teacher son = (Teacher) container.getBean("tSon");
子类和父类的内存地址是否相同?
不同
可以修改父类中的值 (父类不改变,子类中的值不再是继承的值)
可以增加父类中没有的值
父类中被abstract修饰 (抽象类不能创建类对象)
<bean name="teacher" class="com.briup.bean.Teacher" abstract="true">
默认bean单例
abstract="true" 父类只能被继承,不能再去修改,只能子类修改
多个子类创建不同的对象 互不影响
[6]Bean对象在IOC容器中的生命周期
完整的生命周期 life 10步
从容器中取值时,容器已经构建好bean对象,是否取值对构建bean对象无影响
调用container.destroy()方法会销毁单例对象(非单例对象无法销毁)
不完整的生命周期
lazy-init="true"只有使用时才创建
问题:一个类创建时需要关联另一个类,另一个类没有创建,这个类就创建不出来
非单例:每次使用时才会创建对象(因为每次拿时创建的是不同的对象)
设置成非单例 scope="prototype"
[7]xml文件导入其他xml文件配置
<!-- 将多个xml配置文件,合并到一个配置文件 -->使用相对路径
<import resource="student.xml"/>
<import resource="teacher.xml"/>
String[] path = {"com/briup/ioc/imp/teacher.xml","com/briup/ioc/imp/student.xml"};
String[] path = {"com/briup/ioc/imp/import.xml"};
spring容器创建bean对象的方式
spring java里面的类 bean
java里面的属性 property
1.普通bean标签的配置 (反射一定要无参的构造器)
2.工厂模式的生产---》得到的实例对象bean 产品对象
普通的工厂
静态工厂
获得产品的时候 静态方法
配置方法 factory-method
动态工厂
获得产品的时候 非静态方法
配置方法 factory-method
工厂类 批量创建bean对象
xxxFactory
目的:获取xxx
<bean name="fa" class="class...XXFactory">
核心:让spring容器知道谁是工厂类
让spring容器知道调用哪个工厂方法
[8]配置工厂类 通过工厂类获得实例
1.该类是个工厂类,(实现FactoryBean接口,表示这是个工厂类 返回值为目的对象)
public Connection getObject() throws Exception {}
将来想要得到的对象的类型
public Class<?> getObjectType() {}
是否单例
public boolean isSingleton() {return false;}
2.写xml文件 普通的bean对象
<!-- spring提供的类,用来读取外部配置文件 -->
3.test
因为这个类是一个工厂类,所以我们用名字conn在容器中拿对象的时候,
拿到并不是这个工厂类对象,而是这个工厂类对象调用完工厂方法后所返回的对象.
[9]实例工厂获得bean对象
1.类中不用实现接口 普通的类 get set方法+返回工厂类对象的方法
public Connection getConnection() throws Exception {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
}
2.xml 普通的bean+conn为getConnection()返回的对象
<bean name="conn" factory-bean="factory2" factory-method="getConnection">
</bean>
3.test
Connection conn = (Connection) container.getBean("conn");
实例工厂与普通工厂相比,不用实现接口,多一个getConnection方法,xml中多了一个获取连接的bean
[10]静态工厂
1.类中 静态属性+静态代码块 +getConnection
(属性值放在代码块中 所有的值固定)
使用static?因为static类型的属性、代码块在类加载之前构建
2.不用写bean
<bean name="factory3"
class="com.briup.ioc.staticFactory.ConnectionFactory"
factory-method="getConnection"></bean>
3.获取connection类型的bean
自定义
[11]自定义属性编辑器
Spring中我们可以使用属性编辑器来将特定的字符串转换为对象
String--转换-->object
自定义编辑器类 继承PropertyEditorSupport(用于把字符串转成特定的类型)
Spring在注入时,如果遇到类型不一致(例如需要Address类型但是用户传了个String)则会去调用相应的属性编辑器进行转换
spring会调用属性编辑器的setAsText(String str)进行处理用户传的字符串,并调用getValue()方法获取处理后得到的对象
在代码中处理完后需要调用setValue方法,要不然spring调用getValue方法拿不到处理后转换成的对象
setAsText{
封装字符串成对象
setValue(对象);
}
xml中
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.briup.ioc.proEdit.Address" value="com.briup.ioc.proEdit.AddressEditor" />
</map>
</property>
</bean>
key=“无法识别的属性类型”
value="自定义属性编辑器"
[11]自定义事件
事件三要素:事件源 事件监听 事件处理
applicationContext类型对象
1.在spring中我们可以自定义事件,并且可以使用
ApplicationContext类型对象(就是spring容器container)来发布这个事件
2.事件发布之后,所有的ApplicaitonListener(监听器)实例都会被触发
3.并调用指定方法onApplicationEvent()来处理.
1)事件代码
public class rainEvent extends ApplicationEvent{
public RainEvent(Object source) {
super(source);
}
}
2)自定义事件监听器
public class RainListener1 implements ApplicationListener<RainEvent>{
public void onApplicationEvent(RainEvent event) {
//如果发现RainEvent事件发生,则自动调用监听器中当前方法
System.out.println("唐僧大喊:" + event.getSource() + "赶快收衣服喽!");
}
}
3)在配置文件中配置监听器 让当前容器发布对应事件时调用
<bean class="com.briup.ioc.event.RainEventListener1"></bean>
4)test发布事件
container.publishEvent(new RainEvent("打雷了!下雨了"));
监听器监听实现对应的逻辑
[12]注解:ioc中的annotaion配置
@Autowired 只针对类类型 普通属性不能自动注入
1.xml文件中必须有 <context:annotation-config/> 告诉spring识别注解
2.注解可以放在成员变量 set方法 构造器上
3.默认按照byType方式匹配,如果不存在bean 会报异常
4.发现多个同类型 再byName
5. @Autowired可以结合@Qualifier("beanName")来使用 直接byName
@Resource 作用与@Autowired差不多
先byName再byType
@component 将类配置到容器中生成bean对象
1.直接定义bean,无需在xml中定义,两种同时存在,xml中的定义会覆盖类中注解的Bean定义
2.直接写在类上面
3.@Component使用之后需要在xml文件配置一个标签
<context:component-scan base-package="com.briup.ioc.annotation" />
表示spring检查指定包下的java类,看它们是否使用了 @Component注解
4.默认是单例 结合@Scope("prototype")变为非单例(xml中 scope="prototype")
spring
1.可以管理对象的生命周期
2.可以将对象和对象之间复杂的关联关系进行管理
补充:和@Component同样作用
@Controller web
@Service service
@Repository dao
IOC:控制反转
字面含义
实现原理
解决的问题
配置方式