- Spring
- 1.什么是框架
- 2.Spring框架
- 3 Spring IOC具体实现
- 4.Spring IOC原理
- 5.工厂模式
- 规则: properties文件
# 数据结构类型: k-v结构
# 存储数据类型: 只能保存String类型
# 加载时编码格式: 默认采用ISO-8859-1格式解析 中文必然乱码
# user.name , Spring容器会获取的当前计算机的名称 所以慎用
# 例如: user.name=xxxx
user.id=1001
user.username=鲁班七号 - 9.4 Spring注解模式执行过程
- 9.5 Spring中常见问题
Spring
1.什么是框架
说明: 将公共的模块(功能) 进行高级的抽取(接口/父级)形成了通用的代码体.
使用: 引入特定的jar包/class/方法 既可以使用框架中的功能.
实际意义: 简化代码的开发.提高软件的扩展性.
2.Spring框架
2.1 Spring介绍
Spring框架是一个开放源代码的,针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大的IOC、AOP及Web MVC等功能。
Bean: 被spring容器管理的对象称之为Bean
2.2 MVC模型说明
说明: 在大型项目中由于模块众多,如果将所有的项目都写到一起则代码特别的混乱.不便于后期的维护. 所以通过MVC设计模型,将代码进行分级.
实现步骤: 分为3级
1.M(Model) 持久层 代码与数据库进行交互的代码(Mybatis-dao层)
2.C(Control) 控制层 完成某项业务的具体操作过程(Controller层——Service层)
3.V(View) 视图层 一般指用户看到的内容(页面)
MVC模型是大型项目结构设计的设计思想, 目的是为了降低代码的耦合度, 而3层代码结构是设计思想的具体实现方式.
2.3 IOC思想
2.3.1 问题说明
说明: 传统的代码是直接通过new的方式创建对象. 这样的方式将对象与对象紧紧的绑定到一起,不便于代码的扩展.所以需要进行松耦合处理.
2.3.2 IOC说明
控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
说明: 将对象的创建的权利交给Spring管理,由Spring(第三方)管理对象的生命周期(创建/初始化/使用/销毁).
3 Spring IOC具体实现
3.1 添加jar包文件
3.1.1 spring版本说明
3.1.2 引入Spring jar包
4.Spring IOC原理
4.1 Spring容器如何创建对象
1) 当Spring程序执行时,首先会根据配置文件的内容进行解析
2) 当程序解析到bean标签时,则会根据反射的机制实例化对象
3) 将实例化好的对象保存到超大的Map集合中, bean中的Id当做map的Key,实例化好的对象当做Value, 即Map
4) 从容器中获取对象. 则从Map集合中通过id获取对象即可.
4.2 关于反射机制补充说明
反射机制 必然调用对象的无参构造方法
添加有参构造时必须手动添加无参构造
5.工厂模式
5.1 问题
通过spring容器创建的对象一般是通过反射机制调用.但是有的时候由于业务需要, 需要实例化抽象类的对象/复杂的接口对象
说明: Spring提供了工厂模式用于实例化复杂对象
5.2 静态工厂模式
5.2.1 编辑静态工厂
public class StaticFactory{
/通过静态工厂获取数据/
public static Calendar getCalendar(){
return Calendar. getInstance();
}
}
5.2.2 编辑配置文件
<?xml version=”1.0” encoding=”UTF-8”?>
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
5.2.3 编辑测试方法
@Test
public void testStatic(){
ApplicationContext context = new ClassPathXmlApplicationContext(“application.xml”);
Calendar calendar1 = (Calendar) context.getBean(“calendar1”);
System.out.println(“获取当前时间:”+calendar1.getTime());
}
5.3 实例化工厂模式
5.3.1 编辑实例化工厂
public class InstanceFactory{
//获取Calendar对象
public Calendar getCalendar(){
return Calendar.getInstance();
}
}
5.3.2 编辑xml配置文件
<?xml version=”1.0” encoding=”UTF-8”?>
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
//工厂模式实例化对象的方法
@Override
public Calendar getObject() throws Exception {
return Calendar.getInstance();
}
//获取类型
@Override
public Class<?> getObjectType() {
return Calendar.class;
}
//默认条件下spring容器中都是单例对象 节省空间
//对象.方法() 没有安全性问题 提倡使用单例
@Override
public boolean isSingleton() {
return true;
}
} ### 5.4.2 编辑xml配置文件 <?xml version=”1.0” encoding=”UTF-8”?>
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
### 5.4.4 回调执行原理
# 6.关于单例多例说明
## 6.1 关于Spring容器对象创建说明
1.Spring容器中默认的对象都是单例对象(通过构造方法实例化对象)2.有时需要通过多例对象为用户提供服务(数据源链接) ## 6.2 多例对象配置
说明: Spring容器中默认的规则是:容器创建则对象创建.
如果需要配置懒加载 则需要添加额外的属性
2.初始化操作 (一般对对象的属性赋值)
3.用户使用对象(调用其中的方法)
4.对象销毁 (一般都是释放资源, 只要容器关闭,则对象销毁) ## 7.2 编辑xml配置文件
@Test
public void testlife(){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(“application.xml”);
//获取对象
User user = context.getBean(User.class);
//3.用户调用方法
user.say();
//4.只要容器关闭,则对象销毁
context.close();
} ## 7.4 依赖注入(DI) ### 7.4.1 依赖注入介绍 总结: 对象中的属性, 应该由spring容器动态赋值 ### 7.4.2 关于DI注入说明 两种方式 1.Set注入 2.构造注入
### 7.5.2 编辑xml配置文件
xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"](http://www.w3.org/2001/XMLSchema-instance")
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd”>
### 7.6.2 实现对象引用
# 8 Spring容器管理3层代码结构
## 8.1 代码结构
## 8.2 关于特殊字符说明
说明: 由于由于业务需要xml配置文件中 可能会有特殊字符,但是该特殊字符与xml关键字(标签)形成冲突.解决方案: 实现字符串转义 特殊转义字符:
< < 小于号
> > 大于号
& & 和
' ‘ 单引号
" “ 双引号 万能转义字符:
<![CDATA[XXX任意字符]]>
# 9.Spring注解模式
## 9.1 自动装配
### 9.1.1 说明
Spring基于配置文件 为了让属性(对象的引用)注入更加的简单.则推出了自动装配模式autowire.1).根据名称自动装配: autowire=”byName”
2).根据类型自动装配: autowire=”byType”
9.2 注解模式
9.2.1 关于注解的说明
Spring为了简化xml配置方式,则研发注解模式.
Spring为了程序更加的严谨,通过不同的注解标识不同的层级 但是注解的功能一样
1).@Controller 用来标识Controller层的代码 相当于将对象交给Spring管理
2).@Service 用来标识Service层代码
3).@Repository 用来标识持久层
4).@Component 万用注解
9.2.2 编辑配置文件
<?xml version=”1.0” encoding=”UTF-8”?>
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd”>
<!--业务需求2: 不想扫描@controller注解--><br /> **<context:component-scan base-package="com.jt">**<br />** ** <!--通过包扫描 可以加载其他的注解 排除Controller注解--><br />** <context:exclude-filter type="annotation"**<br />** expression="org.springframework.stereotype.Controller"/>**<br />** </context:component-scan>**
9.2.3 属性注解
- 关于注解的说明
- 1.@Autowired: 可以根据类型/属性名称进行注入 首先按照类型进行注入如果类型注入失败,则根据属性名称注入
- 2.@Qualifier: 如果需要按照名称进行注入,则需要额外添加@Qualifier
- 3.@Resource(type = “xxx.class”,name=”属性名称”)
- 关于注解补充: 由于@Resource注解 是由java原生提供的,不是Spring官方的.所以不建议使用
上述的属性的注入在调用时 自动的封装了Set方法,所以Set方法可以省略不写9.3 实现MVC结构的纯注解开发
9.3.1 关于注解说明
注解作用: 一些复杂的程序 以一种低耦合度的形式进行调用
元注解:
@Target({ElementType.TYPE}) 标识注解对谁有效 type:类 method:方法有效
@Retention(RetentionPolicy.RUNTIME) 运行期有效(大)
@Documented 该注解注释编译到API文档中.
9.3.2 关于Spring工厂模式说明
1.Spring源码中创建对象都是采用工厂模式 接口:BeanFactory(顶级接口)
2.Spring开发中需要手动的创建对象时,一般采用:FactoryBean(业务接口)
9.3.2.1 (面试题)BeanFactory 和 FactoryBean 的区别?
BeanFactory是Spring的顶级接口,它是负责生产和管理bean的一个工厂。在Spring中,BeanFactory提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范, 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现
FactoryBean是Spring的业务接口,为IOC容器中Bean的实例化提供了更加灵活的方式,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式. 一般情况下, Spring通过反射机制来创建bean对象, 但在某些情况下, bean对象的创建过程比较复杂(如抽象类), Spring为此提供了一个FactoryBean工厂接口, 用户可以通过实现该接口, 定制实例化Bean的逻辑, 最后通过getBean方法获得的不是FactoryBean实现类对象, 而是实现类中重写的 getObject方法返回的对象.
9.3.3 配置类介绍
说明: 随着软件技术发展,xml配置文件显得臃肿 不便于操作,所以Spring后期提出了配置类的思想.将所有的配置文件中的内容,写到java类中.
9.3.3.1 编辑配置类
@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan(“com.jt”) //设定包扫描的路径
public class SpringConfig {
}
9.3.3.2 编辑测试代码
//通过配置类测试代码
@Test
public void testAnno(){
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserController userController = context.getBean(UserController.class);
userController.addUser();
}
9.3.4 Spring容器管理业务数据@Bean注解
9.3.4.1 @Bean作用
1) 通过该注解,可以将业务数据实例化之后,交给Spring容器管理. 但是@Bean注解应该写到配置类中.
2) 与xml配置文件比较:
1.Spring配置文件写法
2.执行@Bean的方法 将方法名称当做id, 返回值的对象当做value, 直接保存到Map集合中
@Configuration
@ComponentScan(“com.jt”)
public class SpringConfig {
@Bean
public User user(){
User user = new User();
user.setId(101);
user.setUsername(“Spring容器”);
return user;
}
}
9.3.5 Spring动态获取外部数据
9.3.5.1 编辑properties文件 — user.properties
规则: properties文件
# 数据结构类型: k-v结构
# 存储数据类型: 只能保存String类型
# 加载时编码格式: 默认采用ISO-8859-1格式解析 中文必然乱码
# user.name , Spring容器会获取的当前计算机的名称 所以慎用
# 例如: user.name=xxxx
user.id=1001
user.username=鲁班七号
9.3.5.2 编辑配置类
1.@PropertySource
注解用法: @PropertySource(“classpath:/user.properties”)
注解说明: @PropertySource 作用: 加载指定的pro配置文件 将数据保存到Spring容器中
2.@Value
@Value(123) 将123值赋值给Id
@Value(“${user.id}”) 在Spring容器中查找key=user.id的数据.通过 ${} EL表达式语法获取
9.4 Spring注解模式执行过程
1).当程序启动Spring容器时 AnnotationConfigApplicationContext 利用beanFactory实例化对象
2).根据配置类中的包扫描开始加载指定的注解(4个). 根据配置文件的顺序依次进行加载
3).当程序实例化Controller时,由于缺少Service对象,所以挂起线程 继续执行后续逻辑.
当构建Service时,由于缺少Dao对象,所以挂起线程 继续执行后续逻辑.
当实例化Dao成功时,保存到Spring所维护的Map集合中. 执行之前挂起的线程.
以此类推 所有对象实现封装.最终容器启动成功
4). 根据指定的注解/注入指定的对象.之后统一交给Spring容器进行管理.最终程序启动成功.
9.5 Spring中常见问题
9.5.1 接口多实现类情况说明
原则: Spring中规定 一个接口最好只有一个实现类.
业务需求: 要求给UserService接口提供2个实现类.
解决方法: 可以通过@Qualifier注解来获取指定实现类的属性名.
