Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
轻量级:依赖资源少,消耗的而资源少。
EJB(sun的JavaEE服务器端组件模型):步骤繁琐,做一件事,必须要经过很多必须步骤,但是有一些是没有用的,但必须做。
分层:一站式管理,每一层都有一个解决方案。
web层:spring-MVC
service层:spring
dao层:jdbcTemplate -> spring-data
mvc结构,
1.web层:主要是客户端网页,是表层的东西,可接收和返回数据给用户
2.domain层:主控制层,是用户与数据库交互的核心中转站,控制用户数据收集,控制请求转向
3.service层:是业务逻辑层,处理数据逻辑,验证数据,
4.dao层:是持久层,读写数据库
web发出请求—domain接收控制数据转向(可以返回也可以进入service)—service验证数据正确性或者是否符合业务要求—dao存入,读出,依次返回。
IOC:控制反转-------由spring创建对象实例
(之后需要实例对象时,从spring工厂中获得,需要将实现类的全限定名称配置到xml文件中)
AOP:切面编程
1.方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理,用于生成bean
2.AOP编程的支持
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
3.声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
4.方便程序的测试
Spring对Junit4支持,可以通过注解方便的测试Spring程序
5.方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、 MyBatis、Quartz等)的直接支持
6.降低JavaEE API的使用难度
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封 装,使这些API应用难度大大降低
在这里插入图片描述
核心容器:beans,core,context,expression
4 + 1: 4个核心一个依赖
core包:
包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,
是其它组件的基本核心。
beans包:
所有应用都要用到的,它包含访问配置文件、创建和管理bean
以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类
context包:
Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,
如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。
expression包:
Spring表达式语言
commons.logging包:
第三方的主要用于处理日志
位置:任意,开发中一般在classpath中(src)
名称:任意,开发中常用applicationContext.xml
内容:添加schema约束
约束文件的位置:D:\spring视频\1\day33-spring–day01\spring-- day00\jar\spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.xml
UserService是接口,UserServiceImpl为UserService的实现类
旧方法:
通过spring来获取对象
1.在bean中配置文件
2.获取容器
3.从容器中获得对象,访问方法
新方法:
xml文件:
注意:bean里面的class的全限定名一定是以.分隔的,是在文件里复制全名,而不是在目录栏右键复制全名,如下图。
is a :是一个,继承
has a:有一个,依赖( 组合)
eg:
class B{
private A a;//B类依赖于A类
}
依赖:一个对象需要使用另一个对象。
注入:通过setter方法进行另一个对象实例设置。
eg:
class BookServiceImpl{
//之前的方法:接口 = 实现类 (Service和Dao耦合了,只这样写,就耦合)
private BookDao bookdao = new BookDaoImpl();
//spring之后,创建对象 (解耦:service用到的是Dao的接口,不知道具体 的实现类)
private BookDao bookdao;
//setter方法
public void setdao(){}
}
模拟spring执行的过程:
//创建BookService实例
BookService bookservice = new BookServiceimpl(); —>IOC
//创建BookDao实例
BookDao bookdao = new BookDaoimpl(); —>IOC
//将bookdao设置给BookService
bookservice.setdao(bookdao); —DI
xml头配置方法看上面 七
创建BookService实例时,在spring容器(xml)中获取对象,发现BookDao类为其的一个属性,spring自己new了一个BookDao类的对象调用set方法初始化属性。
l 步骤一:确定xsd文件位置
spring-framework-3.2.0.RELEASE\schema\beans
l 步骤二:复制路径
l 步骤三:搜索“xml catalog”
l 步骤四:添加约束提示
BeanFactory:这是一个工厂,用于生产任意bean。
ApplicationContext:是BeanFactory的一个子接口,功能更强大。
ClassPathXmlApplicationContext:用于加载classpath(类路径,src)下的指定的xml,当配置文件被加载,就进行了对象的实例化。
加载xml运行时位置->/WEB-INF/classes/…xml
FileSystemXmlApplicationContext:用于加载指定盘符下的xml
加载xml运行时的位置->/WEB-INF/…xml
通过java web ServletContext.getRealPath();获得具体盘符
运用BeanFactory实现该方法
第一次getBean时初始化Bean
十四.装配Bean基于XML
三种bean的实例化方式:
默认构造
静态工厂
实例工厂
默认构造
必须提供默认构造(采用的默认构造)
静态工厂
1.常用于spring去整合其他的框架(工具)。
2.用于生成实例对象,所有方法必须是静态方法。
工厂的编写
spring的配置
测试类
实例工厂
必须先有实例对象,通过实例对象创建对象。提供的所有方法都是非静态的。
工厂的编写
配置文件
测试类
由于老是要强转太麻烦,所以用上图的方法,在加载class文件时,已经自动强转。
十五.Bean的种类
普通Bean:之前操作的都是普通Bean。
当加载到时,spring底层就直接创建A实例,并返回。
相当于:
A a = new A();
return a;
FactoryBean:是一个特殊的bean,具有工厂生成对象的能力,只能生产特定的对象
bean必须实现FactoryBean接口,此接口提供了方法getObject()用于获得特定的bean。
当加载到时,先创建FB对象,再调用getObject()方法,并返回方法的值。
相当于:
FB fb = new FB();
return fb.getObject();
十六.BeanFactory和FactoryBean的区别
BeanFactory:工厂,用于生产任意的bean
FactoryBean:特殊的bean,用于生产另一个特定的bean。
eg:ProxyFactoryBean:此工厂bean用于生产代理。
//获得代理对象实例,返回的
是代理对象。代理是AOP的核心。
十七.作用域
作用域:用于确定spring创建bean实例的个数。
取值:
singleton:单例,默认值。eg:servlet
测试类:
配置文件:单例是默认值,写不写scope都行。
运行结果:两个实例相同。
prototype:多例,每执行一次getBean将获得一个实例。eg:struts整合spring,配
置action多例。
测试类:
配置文件:
运行结果:两个实例不同。
配置信息:
//scope的取值为上图类别值。
十八.生命周期(11个步骤)
初始化和销毁
1.目标方法执行前或执行后,将进行初始化或销毁。
2.
3.xml配置文件
4.目标类
5.测试类
destroy()方法执行条件
1.容器必须close(),否则不执行。
必须是单例的,多例不执行销毁方法。
销毁方法必须要销毁容器后才知行,试着调用applicationContext.close()方法,出现下图,此对象跟本没有这个方法。因为close()方法在ApplicationContext接口中未定义,而在实现类中定义。可用下面的两种方法进行调用。
法一:ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(xmlpath);
applicationContext.getClass().getMethod("close").invoke(applicationContext);
法二:ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext(xmlpath);
applicationContext.close();
BeanPostProcessor------- 后处理Bean
spring提供的一种机制,只要实现此接口BeanPostProcessor(下图为接口的两个方法) ,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after()。
配置信息:
l Factory hook(钩子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them (装饰者)with proxies(代理).
spring提供了工厂钩子,用于修改实例对象,可以生成代理对象,它是AOP的底层。(有代理就有AOP)
A a = new A();
a = B.before(a); -->将a传递给后处理bean,可以生成代理对象并返回。
a.init();
a = B.after(a);
a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务,提交事务)
a.destroy();
若返回null,a = B.before(a);后面的方法都将执行不了,报空指针异常。
注意:生成代理这一步最好写在 B.after(a)中,若写在B.before(a);中,需将接口实现
类中有的接口却没有的方法声明到接口中去(init(),destroy()),如下图。
后处理bean作用于所有目标类,不是某一个目标类。要想值作用于某一个目标类,通过参数2来进行控制。
十九.属性的依赖注入
依赖注入方式:手动装配 和 自动装配。
手动装配:一般进行的配置信息都采用手动。
基于XML的装配:构造方法,setter方法
基于注解的装配:
自动装配:struts 和 spring整合可以自动装配。
byType:按类型装配
byName:按名称装配
constructor:构造装配
auto: 不确定装配
二十.构造方法注入
XML写法
法一:
法二:
若参数为数字,spring分不清楚类型,默认使用第一个构造方法,会直接按着
index序号装填。
spring能区分出来,第一个参数为字符串类型,检索,发现只能用第二个构造方法。
法三(重要):
type:要写类的全限定名
目标类:
二十一.setter方法注入
配置文件xml
测试类
目标类
报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘personId’ defined in class path resource [com/itheima/f_xml/b_setter/beans.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property ‘pname’ of bean class [com.itheima.f_xml.b_setter.Person]: Bean property ‘pname’ is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
解决方法:加set(),get()方法。
二十二.P命名空间(了解)------对setter方法进行简化
对“setter方法”注入进行简化,替换,而是在
p命名空间使用的前提,必须添加命名空间。
XML配置文件
与二十一中程序效果相同。
二十三.SpEL(了解)------对property进行简化
对进行统一编程,所有的内容都使用value
#{123}、#{‘jack’}:数字,字符串。
#{beanId}:另一个bean应用。
#{beanId.propName}:操作数据。
#{beanId.toString()}:执行方法。
#{T(类的全限定名).字段|方法}:静态方法或字段。
二十四.集合注入
配置文件
数组的配置
list的配置
set的配置
map的配置
上下两种方式都可以,若采用下面那种配置方式,要注明key的类型(是普通值还是引用值)。
property的配置(重要)
目标类(还有相应的getter,setter方法)
结果
二十五.装配Bean基于注解
注解:就是一个类,使用@注解名称。
开发中:使用注解取代xml配置文件。
注解使用前提:添加命名空间让spring扫描含有注解的类。
xml配置文件
xml头添加的文件路径:file:///D:/spring视频/1/day33-spring–day01/spring–day00/jar/spring-framework-3.2.0.RELEASE/docs/spring-framework-reference/html/xsd-config.html
选择复制下图中代码至xml头
schema命名空间:
1.命名空间的声明:
默认:xmls = “” eg:第二行 <标签名> eg:
显示:xmlns:别名 = “” eg:第四行 <别名:标签名> eg:
2.确定schema xsd的文件位置:
xsi:schemaLocation = “名称 位置 名称2 位置2。。。”
内容都是成对的【名称 位置】
目标类
2.web开发,提供3个@Component注解的一个衍生注解(功能一样,取代bean)。
@Repository:dao层
@Service:service层
@Controller:web层
3.依赖注入 ,给私有字段设置,也可以给setter方法设置:
普通值:@Value(“值”)
引用值:
方式1:按照【类型】注入:
@Autowired
方式2:按照【名称】注入1
@Autowired
@Qualifier(“名称”)
方式3:按照【名称】注入2
@Resource(“名称”)
实例:
4.生命周期
初始化:@PostConstruct
销毁:@PreDestroy
5.作用域
@Scope(“prototype”) 多例
二十六.注解和xml混合使用
1.将所有的bean都配置到xml中。
2.将所有的依赖都使用注解。
@Autowired
默认不生效,为了生效,需要在xml中配置:
context:annotation-config
总结:
注解1:
注解2:context:annotation-config
1.一般情况,两个不一起使用,第二个失效。
2.注解1 扫描含有注解(@component等)类,注入注解自动生效。
注解2 只在xml和注解(注入)混合使用时,是注入注解生效。