学习Spring的第一天,记录学习过程。
一、java的三层构架
我说说我对与这三个层次的理解,可能不太规范,欢迎指正。
- 表现层(UL层):主要是用于和用户交互,接受用户输入的数据以及显示数据,处理用户的些请求响应。目前学到的技术有jsp,servlet,cookie,session,filter等。
- 业务逻辑层(service):主要是处理业务逻辑,事务管理,日志管理,监控等。
- 持久层(DAO层):操作数据库,对数据进行增删改查等操作,直接和数据库打交道。例如jdbc,MyBatis等。
二、使用Spring实现步骤
我先实现Spring程序的全过程,有什么细节的地方后面都会一一打讲到。这里的实现过程和我前面学到的MyBatis步骤差不多,创建模块,导入坐标,编写MyBatis核心配置文件,编写Sql映射文件,解决操作sql语句,编写代码。
现在先实现一个Spring程序的全过程:
- 导入Spring包的坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
-
编写dao接口和实现类
我在dao包下写了一个UserDao接口,然后在impl包下用UserDaoImpl类实现UserDao接口的save方法。
-
创建配置文件applicationContext-User.xml
resources————>new————>Xml Configuration File————>Spring Config
-
在配置文件中配置UserDao
在配置文件中加一个bean标签,id属性是找到对应实例的标识,就像html标签里面id属性一样,class属性是你要实例的全限定名。后面还会详细讲到其他属性。
-
使用SpringApl引用配置文件中的Bean实例
这里的对应方法先跟着用,下面的文章会介绍为什么这要用,这样用的目的是什么。
public class UserDaoTest {
@Test
public void UserDaText01(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-User.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
}
最终在控制台上看到save方法执行,就说明我们利用Spring开发不用去new对象,而是先去文件中配置相关的信息,然后通过配置信息直接去Spring容器中拿这些实例化来用。
三、Spring配置文件介绍
1、bean标签
- id 属性:id属性是对应bean表现的唯一标识,就像html里面标签id一样。后面通过getBean方法传参就可以使用id属性。
- class 属性:class属性放的是类的全限定名,Spring容器就是通过这个class里面的值找到的对应类。
- scope 属性:scope有几个主要的值,这几个值就是规定bean标签作用范围的,现在先讲singleton和prototype两个值。
(1)scope值为singleton时:
singleton是scope默认值。Bean实例化个数为一个,在核心配置文件被加载时就创建对应的Bean实例。只要一直不销毁就会一直存在。
(2)scope值为prototype时:
Bean实例化对象可以为多个,每调用一次getBean方法都会实例化一个对应的Bean对象。Bean对象创建后如果长期不使用,就会被垃圾回收站回收。
下面是scope值为singleton时,只加载一次配置文件。就算调用了两次getBean方法,获取到的实例化只是一个。
当scope值为prototype时,就算只加载一次核心配置文件,调用两次getBean方法,获取的实例化是不同的。
- Bean实例化的三种方式
(1)调用无参构造器构造(默认)
每次实例化如果没有配置说明实例化方式,都是利用无参构造器实例化对象的。你可以在对应实体类里面的无参构造方法里面输出内容,每次创建实例化都会输出对应的语句,就足以说明默认无参构造实例的。
(2)工厂静态方法实例化
先在一个定义的类里面写一个静态方法,然后在这个方法里面返回一个实例化对象。
在Bean标签的class属性里面配置定义工厂类的全限定名,然后还需要加上一个factory-method="",里面填调用的静态方法。例如jdbc代码就是通过工厂的方式获取的连接。
(3)工厂实例方法实例化
这种方法实例化就需要在一个工厂里面写一个返回你想要的实例化对象,然后在xml里面先配工厂的坐标,在通过工厂找到类下面的方法。
三、依赖注入
1、什么是依赖注入,为什么要依赖注入?
什么是依赖注入:依赖注入,也叫DI(Dependency injection),就是在创建对象时不在使用原始的通过new 的方法,而是通过Spring容器内部创建实例化对象,对象的创建使用注入的方式,我们直接调用就行。
为什么要依赖注入:在传统代码中,每个对象负责管理自己需要依赖的对象,如果需要切换依赖对象的实现类,就会出现“牵一发而动全身”的情况,我们需要修改多处代码,既耗费大量时间又容易出现错误。为了提高java开发的效率,在遇到这类问题时,我们便可以用依赖注入的方式对传统代码进行优化。依赖注入把对象的创建交给外部IOC容器管理,让代码更具灵活性,能更好地应对需求变动。像上述需要切换依赖对象的实现类时,我们就只需要修改xml文件中的代码,无需修改其他代码,既方便简单又不容易出错。
2、通过set方法注入
实现步骤:
1.先定义一个Use类,设置其属性。我设置了name,age,gender三个属性。
2.实现他们的set方法。
3.在xml文件的Bean标签里面注入属性值。
要是用set方法注入,在bean标签里面就得还有一个子标签。显然子标签就告诉我们要干嘛,property就是属性的意思,我们只需要将对应属性配置进去就好。属性名用name,属性值用value。当然,不同的数据类型属性值的表示不同,单格式大致一样,后面我都会写到。
4.在测试方法可以直接调用他们的值。
从上面的测试类以及运行结果可以看到,我并没有通过new实例化,而是通过bean标签配置对用user类,直接从容器里面拿出这个类使用。我也没有用set方法赋值给user对象,而是通过依赖注入的方法,直接从IOC容器里面就可以取得对应的值,这就是依赖注入的效果。
set方法注入除了用子标签注入属性名,还可以定义p标签注入。就是第三步与其他有所不同。
首先在xml文件前面加入一行:
这一行其实就是挨着bases标签那一行将最后一个bases换成p,然后再在前面定义一个p=就行
然后配置注入的属性
直接在标签里面加上P:对应属性以及属性值就可以配置了。和前面子标签配置效果一样。
3、通过构造器注入
由于set方法注入时我已经演示了普通数据类型的注入方法,现在演示引用型数据类型,其实大部分都差不多。
1.定义一个UserDaoImpl类,设置属性为引用数据类型,这里就以上面创建的user类为例。
2.实现其有参构造器方法。
3.在xml文件的Bean标签里面注入属性值。
配置的时候在bean里面配置一个constructor-arg标签,name是属性名,ref是属性类型,由于前面已经在IOC里面有user类型,这里直接用就行。
4.测试方法测试结果。
同样的原理,既没有new新的UserDaoImpl对象,也没使用set方法赋值,就可以获取属性值,究其缘由还是在xml里面有注入属性值,我们直接拿来用就行。
4、集合数据类型的依赖注入
1.定义一个类,注明属性(这里以list集合和map集合类型属性为例)
2.实现其set方法
3.在xml文件的Bean标签里面注入属性值。
如果是集合类型注入,需要在property里面建一个list或者map标签。如果list或者map的泛型是普通数据类型,值就用value,如果是引用型数据类型,值就用value-ref。然后list的子标签就是list,如果是map集合,就用entry表示。
4.测试方法