一、 spring概述
-
开源的轻量级框架(不依赖很多其他东西–轻量级)
-
两部分核心
- aop 面向切面编程:扩展功能不是修改源代码来实现
- ioc 控制反转:把对象的创建交给spring,通过配置代替之前的new对象操作。
- 一站式框架
在javaee三层结构中,每一层都提供了不同的解决技术
web层:springMVC
service层:spring的ioc
dao层:spring的jdbcTemplate
二、IOC底层原理
思想:高内聚,低耦合
落后的版本:
按之前生成对象的方式,new User(),如果User类发生了改动,那么它使用的所有地方都需要修改。耦合度太高。
后来出现了工厂模式,每次创建调用工厂。这样降低了一些耦合度,不过工厂和对象出现了新的耦合。
IOC如何解决耦合度问题
在工厂类中,创建对象的方式改为:
读取配置文件、解析得到对象的信息 -> 通过对象的信息,使用反射创建类
优点:
如果Service对象发生了改变,那么我们不需要在其他地方改动代码。
如果Service对象路径发生了改变,那么我们只需修改xml配置文件。
耦合度大大减少
这里是XML解析器的学习
三、ioc入门案例
由于上面的底层代码写起来繁琐,Spring提供了几种实现的方法(封装好的轮子),下面是一个小案例,分为几步完成。
第一步:导入jar包
第二步: 创建类User,在类里面创建方法add()
第三步:创建配置文件,配置创建的类
关于配置文件,名称和位置不固定,但是建议放到src下,官方建议起名applicationContext.xml。使用之前还需引入约束schema
Code:配置文件
<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">
<bean id="user" class="cn.itcast.ioc.User"></bean>
</beans>
最后测试一下:
ApplicationContext context =
new ClassPathXmlApplicationContext("bean1.xml");
User user = (User) context.getBean("user");
System.out.println(user);
user.add();
四、深入bean管理的属性
回顾: IOC是要在创建对象的时候解耦,不用new AnotherClass();这种操作。
属性介绍
- id:起的名称,任意命名(不能包含特殊符号,根据id值得到配置对象)
- class:创建的类所在的路径
- name:和id属性一样,可以包含特殊符号(一般不用)
- scope:重要
singleton(单例):创建的对象指向同一个。
prototype(多例):创建的属不同对象。
另外还有其他的,了解即可
五、属性注入(DI)
5.1 概念
希望在创建对象时,能初始化属性的值。
5.2 Spring支持下面的第一第二种形式的初始化
换句话说: 当类的成员变量初始化是通过前两种方式,那就可以用Spring提供的属性注入的方式来实现
(1)第一种set方式的注入:
第一步:创建实例,包含所需注入的属性,和属性的set方法
第二步:配置文件,对Book类进行属性注入
(2)第二种构造方法的注入:
第一步:创建实体类,实现构造方法
第二步:完成配置
这个时候得到的对象,其数据成员的值都会被初始化
六、数据成员是其他类型的属性注入
1) 数据成员是对象:
2)数组:
3) list:
4)map
5)properties
七、用注解的方式实现IOC
上面介绍了Spring提供的对象创建,和属性注入。我们是用过配置文件完成配置,然后ApplicationContext取出对象的,现在要说一种简便的注解方式实现。
注解的结构是这样的
@注解的名字(属性名=值)
注解可以标注在类、方法或者属性上
7.1 准备工作
引入一个新的约束,然后通知Spring开启对包的扫描,具体的看代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
<!--开启扫描,再填入要创建对象所在的包
可以加,号添加多个,表示扫描多个
也可以填高级包名,例如cn.itcast,表示扫描整个包
作用:到包里面扫描类,方法,属性上是否有注解
-->
<context:component-scan base-package="cn.itcast"></context:component-scan>
<!--只扫描属性上面的注解-->
<!--<context:annotation-config></context:annotation-config>-->
</beans>
7.2 使用注解创建对象
在第一节,创建对象是用的
<bean id="user" class = "cn.itcast.xx"></bean>
code: 用注解是这么写的
@Component(value = "user") // <bean id="user" class=""/>
public class User {
public void add() {
System.out.println("Anno add.......");
}
}
Spring还提供了@Component的几种衍生注解,它仅仅是为了让逻辑更加清晰,就目前而言,他们都是等价的
@Controller : Web层
@Service :业务逻辑层
@Repository: 持久层
另外还有一个注解
@Scope(value="prototype") // 多例模式
@Scope(value="singleton") // 默认的,单例
7.3 属性注入
在第一节中,通过在bean标签里面进行配置完成,这里也使用注释。
需求:Service中包含Dao的数据成员,通过调用Service,来调用Dao
第一步:创建Dao和Service对象
code: Dao.class
@Component(value = "dao")
public class Dao {
public void add() {
System.out.println("dao.....");
}
}
code: Service.class
@Component(value = "service")
public class Service {
@Autowired // 或者Resource(name="userDao"),name里面的值填的是Dao类在value里写的值
private Dao dao;
// 不需要set方法了
public void add() {
dao.add();
System.out.println("service.....");
}
}
注意:数据成员的注释,有两种写法,不过推荐使用Resource(name=“userDao”),这样逻辑更加清晰。
7.4 总结:
显然两种方法可以混合一起用,开发中:
创建对象:通过< bean >标签创建
对象上的数据成员: 通过注释(别忘了开启扫描)