框架
作用:
效率,重用性,规范,可维护性,解藕底层
Spring
分层:可以使用spring全部功能也可以使用一部分功能;
full-stack:一站式解决方案,用spring全部功能的话会让开发效率更高;
轻量级:内存消耗低,线程级非进程级;
开源。
架构体系:
底层是核心容器,在核心容器上面提供了AOP等中间层技术,再往上就可以集成别人的一些技术,如dao层集成jdbc、mybatis等。
Spring由工厂模式衍化而来
耦合是不同模块之间掺和在一起,内聚就是一个模块中的功能在本模块中实现,不借助外部,使得模块内紧凑。
应用程序和资源耦合会造成麻烦,因为如果资源变了就要改应用程序然后重新编译、发布,而配置与资源耦合无关紧要,因为如果资源变了我们只需要修改配置文件。
IoC:
传统模式,创建对象的主动权在类手中,IoC模式,创建对象的主动权在spring手中,不需要手动new。
spring案例
创建EE项目
导依赖
maven repository网站上搜spring依赖:
复制依赖到pom文件:
点击加载依赖:
创建资源(即接口和实现类)
创建spring配置文件
在resources目录下,根据提示创建:
以bean的形式管理资源:
id按照规范,用接口名驼峰法,class实现类的全类名:
使用资源
在自带的HelloServlet中:
运行,可以看到输出。
bean注意
name属性
bean的id、name属性都可以作为参数传入到getBean( )中。
scope属性
scope = "singleton"创建出来的对象是单例的,在加载容器(applicationContext)时创建对象,若创建多个对象,内存地址一样,==为true;
scope = "prototype"创建出来的对象不是单例的;
不写默认是singleton。
init-method和destroy-method属性
bean中两个属性:
实现类中两个方法;
当对象创建时执行init方法,销毁时执行destroy方法。
单例模式下, 可以销毁容器时会触发destroy方法:
非单例模式下,对象不是放在spring容器中,spring只是负责new一个新对象,不负责管理,因此不会销毁对象,也就出发不了destroy,只能触发init。
di依赖注入
应用程序依赖资源,spring管理资源,spring为应用程序注入资源。
这一过程在spring的角度叫控制反转,在应用程序程序的角度叫依赖注入,这两个概念是同一件事站在不同角度看而已。
注入的方式有两种:set方法注入(常用)和构造方法注入(不常用)。
set方法注入
通过set方法给service资源注入dao资源。
目录结构:
注入的对象:
被注入的对象:
配置文件:
首先定义好资源,被注入资源是注入资源的私有成员变量,并定义setter方法;
其次注入和被注入的资源要受spring管理,即引用类型变量有bean,基本类型没有;
最后在注入bean中用property子标签声明被注入资源;
name是被注入的对象名(确切的说是set方法名后面的部分驼峰法),ref是被注入bean的id(针对引用类型变量),value是被注入的值(针对基本数据类型,没有bean);
运行输出:
构造方法注入
不用set方法,而是用构造方法:
配置文件:
constructor-arg是构造方法参数,name是参数名,ref是应用类型bean的id,value是基本类型的值。
name用来确定是哪个参数,除了name还有index参数的序号,从0开始,还有type,参数的类型。但是除了name都很鸡肋。
集合类型的注入
在userService中注入userDao和bookDao,在bookDao中注入1个数组和4个集合类型。
BookDao实现类,用set注入,成员分别有set方法:
UserService实现类:
配置文件,不同数据类型的配置不同,map除了value还可以写value-ref指定一个bean:
<bean id="userService" class="com.example.spring_demo.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="userDao" class="com.example.spring_demo.dao.impl.UserDaoImpl"/>
<bean id="bookDao" class="com.example.spring_demo.dao.impl.BookDaoImpl">
<property name="list">
<list>
<value>111</value>
<value>222</value>
</list>
</property>
<property name="props">
<props>
<prop key="乔瑟夫">乔斯达</prop>
</props>
</property>
<property name="arr">
<array>
<value>空条承太郎</value>
<value>波鲁那雷夫</value>
</array>
</property>
<property name="set">
<set>
<value>东方仗助</value>
<value>岸边露伴</value>
</set>
</property>
<property name="map">
<map>
<entry key="乔鲁诺" value="乔巴纳"/>
</map>
</property>
</bean>
运行输出:
注意:userService要有空参构造,否则会报错。
p命名空间(了解)
bean标签里套property标签太繁琐?用p命名空间简化:
在配置文件开头引入p命名空间(下图第4行),url有提示,不用自己敲:
以下两种写法等效:
spring支持el表达式(了解)
bean的属性中只写value不写ref了:
加载并使用配置文件
准备配置文件:
在资源中使用配置文件中的配置项:
容器配置文件开头引入命名空间(下图第4行和倒数1、2行,其中倒数1、2行复制倒数3、4行把3处beans改成context即可):
加载配置文件,:classpath:表示在当前类路径搜索,*通配符,加载所有properties文件:
在bean中使用配置项:
运行输出:
注意:配置文件中写pwd=。。读到的是tomcat的bin路径,应该是个关键字,改成psw就正常。
import引入子配置文件
applicationContext中只写一句:
applicationContext-user中只写user相关的,因为用到book,因此还要引入book:
applicationContext-book中只写book相关的;
三者的开头都一样。
管理第三方资源
pom文件引入阿里数据库连接池Druid(可以根据提示自动补全,先写artifactId):
创建DruidDataSource对象后.set看智能提示发现有很多set方法,而new DruidDataSource()发现只有两个构造方法,其中一个是空参构造,因此选择set注入,配置文件:(注意:变量名是通过.set看智能提示知道的,set方法后半部分的驼峰法)
使用资源:
能打印出来说明创建成功了。