spring简单介绍和使用
spring概念
spring是一个轻量级的,开源的ioc/aop容器,目的是提高开发效率,实现层与层之间的分离。
名词解释:
轻量级:消耗资源少 重量级:消耗资源多
开源:公开的源码
spring三大思想
IOC思想:控制反转:
Inversion of control 控制反转
创建对象权限的反向转移
正常情况下:由使用者创建类的对象 谁用谁创建 new类()
反转:将创建对象的权限交给spring容器,由spring容器统一创建对象,我们使用时,只需要从容器中获取对象即可。
DI:依赖注入
跟ioc思想实际上是一回事,只是描述的方向和形式不同。
IOC强调,对象的创建权有自己创建改为有spring容器创建,也就是创建权的反向转移。
DI强调,对象的属性值依赖spring容器注入。
aop:面向切面编程
层与层:
controller(控制层) service(服务层) mapper/dao(持久层)
控制层调用业务层,业务层调用mapper/dao
耦合:控制层中有service层的代码,service层有mapper层代用的代码,就是每层和每层连接的太紧密了
spring IOC
第一步:创建一个maven项目
file—new—project—>maven—>create from archetype —>maven archetype-quickstart---->next(GroupId 起个名字)(artifactid 起个项目名)
项目创建完成之后在main包下创建resources包并添加为资源目录
第二步:使用spring,引入jar包
使用spring导入jar包的版本号要一样
spring-beans-***.jar
spring-context-***.jar
spring-core-***.jar
spring-expression-***.jar
spring-context-support-***.jar
commons-logging.jar
但是当你使用maven时只需要在maven仓库中搜索spring-context,spring-context-support-***(注意:导入spring的包时版本号要一致),commons-logging粘到pom.xml文件中maven会自动导入依赖的相关jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
第三步:在resources中,创建一个springxml文件
创建步骤如下:
文件命名为applicationContext.xml(注意:一般spring命名规范都是applicationContext.xml)。applicationContext.xml文件中的内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
步骤四:创建实体类并在applicationContext.xml中配置
在pojo包中创建一个省的实体类:
public class Provinces implements Serializable{
private int id;
private String provinceid;
private String province;
//创建setter、gettter、toString
}
在applicationContext.xml文件中配置
<bean id="provincesId" name="provinces" class="com.lanou.pojo.Provinces">
<property name="id" value="1"></property>
<property name="province" value="北京市"></property>
<property name="provinceid" value="110000"></property>
</bean>
<!--测试延迟加载时这里注释掉-->
<bean id="provincesId2" name="provinces2" class="com.lanou.pojo.Provinces"></bean>
获取bean对象
在测试包中创建测试类
四种
1 通过bean的id获取
2.通过bean的name获取
3.通过类型获取(当两个bean相同时就会报org.springframework.beans.factory.NoUniqueBeanDefinitionException 没有唯一的Bean定义异常)
public void springObgect() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//1 通过bean的id获取
Provinces p = (Provinces) context.getBean("provincesId");
/*p.setId(1);
p.setProvinceid("100010");
p.setProvince("北京");
System.out.println(p.toString());*/
//2.通过bean的name获取
//在配置文件中利用setter方法给对应的属性赋值
//Provinces p2 = (Provinces) context.getBean("provinces");
//System.out.println(p2.toString());
//3.通过类型获取
//Provinces p3 = context.getBean(Provinces.class);
//System.out.println(p3.toString());
//4.通过名称和类型
Provinces p4 = context.getBean("provinces",Provinces.class);
System.out.println(p4.toString());
}
测试初始化和销毁
在Provinces中加入init()方法
public void init(){
System.out.println("-----------init 初始化---------------");
}
public void destroy(){
System.out.println("---------destroy 销毁的方法------------");
}
在配置文件中bean中加入init-method=“init” destroy-method=“destroy”
<bean id="provincesId"
name="provinces"
class="com.lanou.pojo.Provinces"
init-method="init"
destroy-method="destroy"
>
<property name="id" value="1"></property>
<property name="province" value="北京市"></property>
<property name="provinceid" value="110000"></property>
</bean>
在测试类中创建测试方法
@org.junit.Test
public void testInitDestroy(){
//在Provinces中加入init()方法
//在配置文件中bean中加入init-method="init" destroy-method="destroy"
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Provinces p = context.getBean("provinces",Provinces.class);
System.out.println("创建对象之后");
}
结论:当获取bean对象时就会执行Provices中的初始化方法
测试单例多例模式
scope:作用域范围
prototype:多例
- 创建一次是一个新的对象
singleton:单例(懒汉式 饿汉式)
- 不管如何创建,只能是一个对象
1 在配置文件中bean中加入 scope="singleton"或 scope=“prototype”
<bean id="provincesId"
name="provinces"
class="com.lanou.pojo.Provinces"
init-method="init"
destroy-method="destroy"
scope="singleton"
>
<property name="id" value="1"></property>
<property name="province" value="北京市"></property>
<property name="provinceid" value="110000"></property>
</bean>
在测试类中测试
@org.junit.Test
public void testSingletonPrototype(){
//在配置文件中bean中加入 scope="singleton"
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Provinces p = context.getBean("provinces",Provinces.class);
Provinces p1 = context.getBean("provinces",Provinces.class);
//测试单例和多例时判断是否是同一个对象
System.out.println(p==p1);//true(Singleton) false(prototype)
}
延迟加载
lazy-init:是否延迟加载当前对象
只在单例模式下有效(多例模式下每次都需要调用无参构造对象,所以无效)
- false 立即加载 加载当前spring配置文件时就创建对象
- true 延迟加载 当第一次调用对象时加载
在配置文件中的bean加入lazy-init=“true”
<bean id="provincesId"
name="provinces"
class="com.lanou.pojo.Provinces"
init-method="init"
destroy-method="destroy"
scope="singleton"
lazy-init="true"
>
<property name="id" value="1"></property>
<property name="province" value="北京市"></property>
<property name="provinceid" value="110000"></property>
</bean>
在无参构造中加入输出语句
public Provinces() {
System.out.println("无参构造方法Provinces");
}
在测试类中测试
@org.junit.Test
public void testLazyInit(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("创建对象之前");
Provinces p = context.getBean("provinces",Provinces.class);
System.out.println("创建对象之后");
}
静态工厂
创建ProvincesFactory工厂类
public class ProvincesFactory {
/*
静态工厂
*/
public static Provinces create(){
System.out.println("静态工厂");
return new Provinces();
}
}
在配置文件中配置
<bean id="provincesFactory" class="com.lanou.pojo.ProvincesFactory" factory-method="create"></bean>
在测试类中进行测试
@org.junit.Test
public void testStaticFactory(){
//加载spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Provinces p = context.getBean("provincesFactory",Provinces.class);
System.out.println(p.toString());
}
非静态工厂
在ProvincesFactory工厂类中创建非静态方法
/*
非静态工厂
*/
public Provinces create2(){
System.out.println("非静态工厂");
return new Provinces();
}
在xml文件中配置
在非静态工厂测试时,去掉静态工厂中的factory-method=“create”,不然会报错,找不到create2方法
<!--静态工厂类对象 测试非静态的时候删了factory-method="create"-->
<bean id="provincesFactory" class="com.lanou.pojo.ProvincesFactory"></bean>
<!--非静态工厂类对象-->
<bean id="provincesFactory2" factory-bean="provincesFactory" factory-method="create2"></bean>
在测试类中测试
@org.junit.Test
public void factoryFactory(){
//加载spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取provinces对象
Provinces provinces = context.getBean("provincesFactory2", Provinces.class);
System.out.println(provinces.toString());
}
层与层之间的调用
在service层中创建ProvincesService
public interface ProvincesService {
public void getProvince(int id);
}
在service包下创建Impl包,在Impl包中创建ProvincesServiceImpl并实现ProvincesService接口
public class ProvincesServiceImpl implements ProvincesService {
@Override
public void getProvince(int id) {
System.out.println("Impl方法执行---"+id);
}
}
在servlet包中创建
public class ProvincesServlet {
private int id;
private ProvincesService provincesService;
public void getProvince() {
provincesService.getProvince(id);
}
在配置文件中配置
<bean id="provincesService" class="com.lanou.service.serviceImpl.ProvincesServiceImpl"></bean>
<bean id="provincesServlet" class="com.lanou.servlet.ProvincesServlet" scope="singleton" lazy-init="true">
<property name="id" value="100"></property>
<!--ref指向上一个id-->
<property name="provincesService" ref="provincesService"></property>
</bean>
测试
@org.junit.Test
public void testDI(){
//加载spring配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ProvincesServlet servlet = context.getBean(ProvincesServlet.class);
servlet.getProvince();
}