刚刚通宵爆肝完Maven继续搞Spring,看在我掉头发掉一地的份上,有所不对的地方还请懂的大佬指正,小生在这有礼啦~
目录
Spring简介
- 概念:spring是一个开源的框架,管理其他的框架。
- 核心:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
- 具体应用:日志监控,性能监控,事务控制等……
- spring框架是一个分层架构,共包含了20多个模块,我只列举其中一些:
- Core和Beans模块:提供了Spring最基础的功能,提供IOC和依赖注入特性
- context: 基于Core和Bean来构建,它提供了用一种框架风格地方式来访问对象,有些像JNDI注册表。
Context封装包继承了beans包的功能,还增加了国际化(I18N),事件传播,资源装载,以及透明创建上下文,
例如通过servlet容器,以及对大量JavaEE特性的支持,如EJB,JMX.核心接口是ApplicationContext. - Expression Language: 表达式语言模块,提供了在运行期间查询和操作对象图的强大能力。支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从spring容器获取Bean,它也支持列表投影、选择和一般的列表聚合等。
- JDBC模块,提供对JDBC的抽象,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。
- ORM模块,提供了常用的“对象/关系”映射API的集成层。其中包括JPA、JDO、Hibernate和iBatis.利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如简单声明式事务管理。
- OXM模块,提供一个支持Object和XML进行映射的抽象层。其中包括JAXB、Castor、XMLBeans、JiBX和XStream.
- JMS模块,提供一套“消息生产者、消费者”模板用于更加简单的使用JMS,JMS用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
- Transaction模块,支持程序通过简单声明式事务管理,只要是Spring管理对象都能得到Spring管理事务的好处,即使是POJO,也可以为他们提供事务。
web支持: - web-socket模块,websocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,spring支持websocket通信。
- web模块,提供了基础的web功能。例如多文件上传、集成IOC容器、远程过程访问以及对webservice支持,并提供一个RestTemplate类来提供方便的Restful services访问。
- web-servlet模块,提供了web应用的model-view-controller(MVC)实现。spring mvc框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与spring其他技术协作。
- web-portlet模块,提供了在portlet环境下的mvc实现。
- aop模块,提供了符合aop联盟规范的面向切面的编程实现,让你可以定义如方法拦截器和切入点,从逻辑上讲,可以减弱代码的功能耦合,清晰地被分离开。而且,利用源码级地元数据功能,还可以将各种行为信息合并到你的代码中。
aspects模块,提供了对AspectJ的集成。 - Instrumentation模块,提供一些类级的工具支持和ClassLoader级的实现,可以在一些特定的应用服务器中使用。
Spring优点
- Spring能帮我们根据配置文件创建及组装对象之间的依赖关系。
- Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
在传统应用程序当中,我们如何来完成数据库事务管理?需要一系列“获取连接,执行SQL,提交或回滚事务,关闭连接”,而且还要保证在最后一定要关闭连接,多么可怕的事情,而且也很无聊;如果采用Spring,我们只需获取连接,执行SQL,其他的都交给Spring来管理了,简单吧。所以,Spring能非常简单的帮我们管理数据库事务。 - Spring还提供了与第三方数据访问框架(如Hibernate、mybatis,ibatis,JPA)无缝集成,而且自己也提供了一套JDBC访问模板,来方便数据库访问,比如jdbcTemplate ,redisTemplate。
- Spring还提供与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
- Spring能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)。
- 低侵入式设计,代码污染极低。
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺
- Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
- AOP编程的支持:
spring提供面向切面编程,可以方便的实现对程序进行权限拦截,运行监控等功能。
下面我直接先说起Spring core和bean最基础的IOC和DI,以后有时间会整理其他
Spring IOC
- IOC也就是Inversion Of Control:直译就是控制反转,主要用来做对象实例化的,有了这东西就不需要自己频繁的new了
- 其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是主要的,要获取什么资源都直接去调用,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IOC容器来创建并注入它所需要的资源。IoC很好的体现了面向对象设计法则之一------即由IoC容器帮对象找相应的依赖对象并注入(也就是DI),而不是由对象主动去找。
- 总结:IOC的本质就是将原先由自己管理对象的生命周期,现在交给Spring工厂去统一的管理bean的生命周期。
Spring-DI
DI(Dependency Injectio):也就是将spring创建的对象赋值给类中的空引用,注意:一定得是空,也就是光创建不给它搞对象,不然报错。
依赖注入:通过bean中的property给类中的属性赋值。
Spring 实例创建
以下部分可以去看看天天向上的菜鸡杰!!的博客,他这部分写的很好,我直接按我自己理解写了,虽然有部分会照搬,嘿嘿~。
Spring依赖配置
我直接在Maven项目的基础上写这个了哈
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
导入后在Maven Dependencies找到对应Spring的jar包就说明配置成功
再去src/main/resources创建spring.xml,规定其约束
- 约束配置如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
注意:如果此时去其他java类里创建与spring.xml相同的或者想相对应的对象,spring.xml创建的bean对象会把它覆盖掉,部分Eclipse版本会直接报错
- 之后便是如何在spring.xml创建对象
<bean name="对象名" class="创建对象类的路径">
<!-- 通过property赋予属性名,这个基本用于两个bean对象的联系 -->
<!-- ref(reference):参照一个bean引用名称为name的 -->
<property name="属性名" ref=""></property>
</bean>
我给个实例给大家参考一下吧,这样讲感觉有点抽象
<bean name="studao1" class="com.it.dao.StudentDAO"></bean>
<bean name="stusv1" class="com.it.services.StudentService">
<property name="studao" ref="studao1"></property>
</bean>
<bean name="stuact" class="com.it.action.StudentAction">
<property name="stusv" ref="stusv1"></property>
</bean>
注意:此方法需要在对应类里创建set方法接收值,不然报空
除了以上讲的方法注入也就是在spring.xml里写bean对象的方法,或者说属性注入,还有其他注入方式
构造注入
这个和属性注入其实区别不大,主要是这个是用有参构造器方法传值,而不是set方法传值,这样能一次传多个
具体步骤与如下:
- 首先在对应类创建有参构造方法
- 其次就是在spring.xml里配置节点代码如下:
<!-- index:是索引,指定注入的属性,从0开始,如:0代表瞎坤吧起名字,1代表瞎坤吧起id; -->
<!-- type:是指该属性所对应的包地址或者说类型名,如Persondao对应的是com.aptech.dao.PersonDAO; -->
<!-- value:当注入的不是依赖对象,而是基本数据类型时,就用value-->
<!-- 换句话说,如果参数属性不是某个对象而是具体数值的话,要用数值写死的方式(value)来写,也就是说ref,和value属性不能同时出现 -->
<!-- ref:是指引用的依赖对象; -->
<bean id="瞎坤吧起名字" class="就是对应类"></bean>
<bean id="瞎坤吧起id" class="就是对应类">
<constructorarg index="0" type="com.aptech.dao.PersonDAO"ref="personDao"></constructor-arg>
<constructor-arg index="1" value="Spring学习"></constructor-arg>
</bean>
- 同属性注入,构造注入的结构体对象只能创建不能搞对象
属性注入和构造注入比较
-
属性注入优点:
Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题。
尤其在某些成员变量可选的情况下,多参数的构造器更加笨重。 -
构造注入优点:
对于依赖关系无需变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定,无须担心后续的代码对依赖关系产生破坏。
依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系,对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。
Spring实例化xml配置文件bean的三种方式
- 使用构造器实例化bean,也就是直接创
- 静态工厂实例化bean,配置如下:
以下是静态工厂(也就是所谓的饿汉模式)设立:
//能够实现单例,让一个类只能被实例化一次
public class staticFactory {
private static StaticFactory staticFactory = new StaticFactory();
public static staticFactory getBean (){
return staticFactory;
}
public void say(0) {
Systen.out.println ("new Instance! ");
}
}
以下是xml配置文件设立:
<!-- 配置文件: -->
<!--方法二:使用静态工厂方法实例化bean -->
<!--method指调用工厂方法 -->
<bean id="staticFactory" class="com.test.StaticFactory" factory-method="getBeat
- 实例工厂实例化bean
3.1 配置接口
3.2 配置接口实现类
3.3 配置接口实现类的实例化类,真坤吧绕口,以及得带有静态方法
3.4 xml文件配置
我给个例子,大家体会体会
//接口UserDao:
package com.dao;
import com.model.User;
public interface UserDao {
public void add(User user);
public void findByid(String id);
}
//实现类UserDaoImpl:
package com.dao.impl;
import com.dao.UserDao;
import com.model.User;
public class UserDaoImpl implements UserDao {
private String hello;
@Override
public void add(User user) {
System.out.println("方法三:qwqwqwq!!!");
}
@Override
public void findByid(String id) {
}
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
}
//接口实现类的实例化类
public class InstanceBean {
private static UserDao userDaoA = new UserDaoImpl();
private static UserDao1 userDaoA1 = new UserDaoImpl1();
public static UserDao getBeanInstance() {
return userDaoA;
}
public static UserDao1 getBeanInstance1() {
return userDaoA1;
}
}
以下是xml文件配置:
<!-- 首先是创建接口实现类的实例化bean -->
<bean id="instanceBean" class="com.test.InstanceBean"/>
<!-- 再是创建实例化工厂的bean -->
<bean id="userDao" factory-bean= "instanceBean" factory-method="getBeanInstance"></bean>
这样能相对减少一些xml配置
Spring容器手动加在的三种方式
- 通过类路径获取配置信息
代码如下:
//加载spring容器--手动获取spring容器
//ClassPathXmlApplicationContext也就是通过类路径获取xml配置信息的方法
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
//从容器中获取需要的StudentAction对象引用。
StudentAction stuact=(StudentAction) context.getBean("stuact1");
stuact.add();
这种用法常用在测试以及寻常文件配置中
- 通过绝对路径
通过绝对路径也就是通过文件系统路径论获取配置信息,具体配置如下:
ApplicationContext context=new FIleSystemXmlApplication(“d://…..”);
StudentAction stuact=(StudentAction) context.getBean("stuact1");
stuact.add();
这种用法常用在更换整体配置信息
- 通过BeanFactory获取配置文件
也就是通过bean工厂的方式,具体配置如下:
BeanFactory factory=new XmlBeanFactory(new FileSystemResource(“d://……”));
StudentAction stuact=(StudentAction) context.getBean("stuact1");
stuact.add();
注解我会在Spring-MVC文章里讲,如有错还请大家纠正,下期再见~