Spring介绍
Spring是开源的、轻量级的框架,是管理对象的容器。主要功能有:IOC、AOP。
Spring 关于jdbc的支持、与Junit的整合测试。
一、Spring环境搭建
1、导入包 4个核心包+2个日志包
其中log4j是非必须包,当spring版本较低时,可以兼容,建议导入。
2、创建一个对象
3、将对象注册到spring容器中
默认spring配置文件可以任意起名,但建议写成applicationContext.xml
默认路径可以是src下的任意路径,但是建议写在src下(其实就是classpath下)。
4、约束的导入
5、编写xml
6、测试
Spring中的核心概念
IOC: Inverse of Control 控制反转
之前对象由我们开发人员创建,对象关系由我们维护,现在交由spring容器创建和维护类之间的关系。控制权反转了,这就是IOC。
DI:依赖注入
注入的方式:set方法注入,构造方法,字段注入
注入类型:
基本类型:8大基本数据类型
引用数据类型:对象(包括String)
实现IOC思想的很重要的技术支持。
AOP:面向切面编程(随后讲解的内容)
BeanFactory:
Spring原始接口,该接口实现类的一个特点是每次获取bean时,才会创建对象。
所以占用内存较小,但是速度不快。
ApplicationContext:
每次容器一起动就会创建对象,还有很多其他功能。占用内存较大,但是速度快。
两个实现:
ClassPathXmlApplicationContext 从类路径中加载配置文件
FileSystemXmlApplicationContext 从绝对路径中加载配置文件
ClassPathXmlApplicationContext 常用,但是将来不测试代码的时候,我们其实可以交给web.xml。
Spring配置(包括属性注入)
1、bean标签
Class: 被管理对象的完整路径
Name:给被管理的对象起个名字,便于获取对象的时候使用。
Id:与name属性一样,但是名字不能重复。
建议使用name。
Scope:singleton(默认值) 单例对象
在spring中只创建一个实例化对象
Prototype: 多例原型
在spring中创建多个对象,一般我们不会指定为多例对象,但是如果将来整合structs2整合的时候,需要指定为多例,多例时,web容器启动时,不会创建该对象,每次使用时创建一次,即使用一次创建有一次。
Init-method:
创建一个方法作为生命周期的初始化方法,spring会在创建对象的时候调用该方法。
Destory-method:
创建一个方法作为生命周期的销毁方法,spring会在销毁对象的时候调用该方法。
2、spring容器创建对象
1)空构造方法(最重要)
<bean name="admin" class="com.jnmd.pojo.Admin></bean>
2)静态工厂
<!-- 通过静态工厂创建 -->
<bean name="admin2" class="com.jnmd.spring.BeanFactory" factory method="createAdmin"></bean>
3) 实例工厂
<!-- 通过实例工厂创建 -->
<bean name="beanFactory" class="com.jnmd.spring.BeanFactory"></bean>
3、属性注入
1)set方法注入
<bean name="admin" class="com.jnmd.pojo.Admin">
值类型的注入
<property name="username" value="kangshifu"></property>
<property name="password" value="z1h2i3y4o5U"></property>
对象类型的注入
<property name="car" ref="car2" ></property>
</bean>
<bean name="car2" class="com.jnmd.pojo.Car">
<property name="name" value="五菱宏光"></property>
<property name="color" value="红色"></property>
</bean>
2)构造方法注入
<bean name="admin" class="com.jnmd.pojo.Admin">
参数数量和类型一定要和构造方法保持一致
<constructor-arg name="username" value="zhangsanfeng"></constructor-arg>
<constructor-arg name="password" value="2342343" type="java.lang.Integer"></constructor-arg>
<constructor-arg name="auth" value="zengshangaicha"></constructor-arg>
<constructor-arg name="car" ref="car2"></constructor-arg>
</bean>
3)通过p名称空间注入
<!-- =================通过P名称空间注入(了解)=========================== -->
<bean name="admin" class="com.jnmd.pojo.Admin"
p:username="zhangsan" p:password="adfdfd" p:car-ref="car2"></bean>
补充内容:spel获取值 #{对象.属性名称}
<!-- =================spel(了解)===========================
spring EL表达式 只在普通属性上使用,对象类型不适合使用
-->
<bean name="admin2" class="com.jnmd.pojo.Admin">
<property name="username" value="#{admin.username}"></property>
<property name="password" value="#{admin.password}"></property>
<property name="car" ref="car2" ></property>
</bean>
4)复杂类型注入
<bean name="collection" class="com.jnmd.pojo.CollectionDemo">
<!-- 可行,但是只能添加一个 -->
<!-- <property name="arr" value="hehe"></property> -->
<!-- array注入,可以注入多个元素 -->
<property name="arr">
<array>
<value>hehe</value>
<value>haha</value>
<value>heihei</value>
<!-- <ref bean="car"/> -->
</array>
</property>
<property name="list">
<list>
<value>java</value>
<value>js</value>
<value>h5</value>
<ref bean="car2"/>
</list>
</property>
<property name="map">
<map>
<entry key="url" value="localhost:3306/crm"></entry>
<entry key="username" value="yywereu"></entry>
<entry key="password" value="23748329"></entry>
<entry key-ref="admin" value-ref="car2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="username">zhangsan</prop>
<prop key="grade">5年级</prop>
</props>
</property>
</bean>
<!-- 位置在bean之外,注意路径 ,导入成功后,当前的xml就可以使用之前的bean-->
<import resource="applicationContext.xml"/>
补充内容:
一、复制一个项目,记得修改项目右键 web 功能中的内容
二、快速查看一个接口的所有实现类
鼠标放上去,然后Ctrl + T 即可
三、web容器加载Spring容器代码
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
不配置context-param的话,默认加载WEB-INF/applicationContext.xml
Spring注解
一、准备工作,导入context约束
Jar包准备:(4+2+1【aop】)
Bean的扫描: 将某个包下的java类以及子包下的类都加载到spring容器中,需要配合注解。
<!-- 扫描包
扫描包com.jnmd.pojo下所有的bean到容器中来,
包括子孙包
本质是扫描注解:@Component 组件
@Service //service层
@Controller // web层
@Repository // dao层
-->
<context:component-scan base-package="com.jnmd.pojo">
</context:component-scan>
@Component 组件 将该注解修饰某个类,会被扫描器扫描到容器中。
还有其他三个衍生类(目前功能都是一致的)
* @Controller :web层
* @Service :业务层
* @Repository :持久层
属性注入的注解(使用注解注入的方式)
@Value :用于注入普通的类型
@AutoWired: 自动注入
*默认按照类型进行装配
*如果同一类型按照名称装配时,使用@Qualifier(“名称”)
@Resource 相当于:
@Autowired 和@Qualifier 一起使用.
Bean的作用范围的注解:
@Scope(scopeName=””)
* singleton :单例
* prototype :多例
如何理解单例和多例?
在Spring中是存放对象的,不是存放类的,所有同一个类可以在Spring创建多个实例。
但是一个实例在容器中只存在一份,这是单例,存在多份(即new了多次)这叫多例。
Bean 的生命周期的配置:
@PostConstruct :相当于init-method
@PreDestroy :相当于destroy-method
整合Junit测试(了解一下)
需要导入spring中的测试包,并且要求junit包的版本是4.9及以上版本
代码案例:
//帮我们创建容器
@RunWith(SpringJUnit4ClassRunner.class)
//创建容器时,需要指定配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJUnit {
@Resource(name="car1")
private Car car1;
@Resource(name="car2")
private Car car2;
@Test
public void testAdmin(){
System.out.println(car1==car2);
}
}
常见错误总结:
异常:某个类找不到,而这个类还是一个第三方的类,所以判断少包(aop)
异常:SpringJUnit4ClassRunner需要4.9及以上更高版本支持
Caused by: java.lang.IllegalStateException: Failed to find class [org.junit.runners.model.MultipleFailureException]: SpringJUnit4ClassRunner requires JUnit 4.9 or higher.
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<clinit>(SpringJUnit4ClassRunner.java:102)
... 18 more
如何设置workspace字符集?
选择windows–>properties
设置完之后,如果文件原来不乱码的文件变成了乱码,选中乱码文件,Ctrl+z 即可解决。