Spring-1

Spring 应用开发

Spring 是一个轻量级的控制反转 IoC/DI 依赖注入和面向切面 AOP【面向方面】的开源容器框架,是一个开源的 Java/Java EE 全功能栈 full-stack 的应用程序框架。通过 IoC 容器,关注点便放到了需要实现的业务逻辑上;

AOP 可以动态增强业务方法。编写普通的业务逻辑 Bean 是非常容易而且易于测试的,因为它能脱离 JavaEE容器单独进行单元测试

Spring 特点

解决企业应用开发的复杂性,JavaEE 的一站式解决方案

能将 Spring 框架和其它框架 Struts2、hibernate 区分开来

Spring 是一个非常优秀的轻量级框架,通过 IoC 容器,关注点便放到了需要实现的业务逻辑上对 AOP 的支持则让动态增强业务方法。编写普通的业务逻辑 Bean 是非常容易而且易于测试的,因为它能脱离J2EE 容器单独进行单元测试

最后的一步便是在 Spring 框架中将这些业务 Bean 以 XML 配置文件(Annotation)的方式组织起来,它们就按照预定的目标正常工作了

目的:解决企业应用开发的复杂性

功能:使用基本的 JavaBean 代替 EJB,并提供了更多的企业应用功能

范围:任何 Java 应用,不适合做分布式系统开发 EJB

Spring说明

1、Spring 是一个开源的依赖注入 IoC/DI 和面向切面 AOP 的容器框架。它的主要目是简化应用的开发。

2、方便解耦,简化开发。通过 Spring 提供的 IoC 容器,我们可以将对象之间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。有了 Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

3、Spring AOP 提供了很多基础但是与业务逻辑无关的功能,比如:事务管理、与持久化框架、显示层框架集成等。

4、Spring 还提供了自己的 MVC 实现和 JdbcTemplate 来简化数据操作

5、声明式事务的支持。在 Spring 中,我们可以从单调烦闷的事务管理代码中解脱从来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

6、方便程序的测试。可以用非容器依赖的编程方式进行几乎所有的测试工作,在 Spring 里,测试不再是昂贵的操作,而是随手可做的事情。

7、方便集成各种优秀框架。Spring 不排斥各种优秀的开源框架,相反,Spring 可以降低各种框架的使用难度,Spring 提供了对各种优秀框架(如 Struts,Hibernate、Hessian、Quartz 等)的直接支持。

Spring 主要功能

1、简化企业级开发。封装了大部分的企业级服务,提供了更好的访问这些服务的方式;提供了 IoC,AOP 功能的容器,方便编程。

2、遵循 Spring 框架的应用程序,一定是设计良好的,针对接口编程,这样就简化了企业级程序的设计。

Hello Spring

1、添加依赖,测试的是 IoC 功能

<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-context-supportartifactId>
    <version>5.3.27version>
dependency>

Spring-1_第1张图片

2、在 resources 目录下创建核心配置文件,建议名称为 applicationContext.xml

说明 xml 语法的方法有 2 种:dtd 和 xsd


<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p" 
    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">
beans>

3、定义一个受管 bean。将一个定义好的类交由 Spring 容器负责管理,只需要在 applicationContext.xml 中进行配置说明即可

<bean id="now" class="java.util.Date"/> id 标识符,用于区分不同的受管 bean,
不允许重名,一般建议命名规则为 Java 中变量的命名规则,实际上没有这么严格;
class 为受管 bean 的类的全名。
<bean id="df" class="java.text.SimpleDateFormat" scope="prototype"> 
由于受管 bean 默认情况下只有一个对象实例,也就是单例模型;
可能会出现线程安全问题,所以 scope=prototype 采用原型模式,获取一次 bean则自动创建一次
    <constructor-arg value="yyyy 年 M 月 d 日 E"/> 定义创建 SimpleDateFormat 时的构造器参数
bean>

4、编程获取受管 bean

Resource resource=new ClassPathResource("applicationContext.xml");
BeanFactory factory=new XmlBeanFactory(resource); //获取 IoC 容器的引用
Date now=(Date) factory.getBean("now"); //按照名称从 Spring 容器中查找受管 bean,对应配置受管 bean时的 id 值
DateFormat df=factory.getBean(DateFormat.class); //按照类型从 Spring 容器中查找受管 bean,请务必注意
//不论采用 id 查找还是采用按照类型查找,都只能找到一个受管 bean,否则异常
String s = df.format(now);
System.out.println(s);

基本框架结构

Spring 是一种 JavaEE 开发中的一站式解决方案,所以其中包含的内容比较多,为了避免在应用中添加无用功能,所以 Spring 采用了非强制性的模块化结构,在具体应用中,可以根据应用所需要的功能进行选择添加Spring4.x 分为 6 大模块,包括 20 多个子项目。注意从 Spring6 开始使用 JDK17,抛弃了 JDK8

Spring-1_第2张图片

1、Core container 核心容器,Spring 中所有的功能都是依赖于核心容器。beans core context context-support expression

2、AOP 和 apects 提供 AOP 编程技术支持: aop aspects,另外还有其它的不是 Spring 的 jar

3、Data Access/Integration 针对 DAO 编程和 ORM 整合的支持: jdbc orm tx

4、Web 提供了整合表现层框架和对应的 web 解决方案 SpringMVC:web webmvc

5、Instrumentation 底层基础,是一种没有图形界面的,具有启动能力的,用于监控其他类的工具类

6、Test 提供了单元测试的支持,要求 junit4.8+版本

Spring 框架 4 大原则

1、使用 POJO 进行轻量级和最小侵入式开发。其中 POJO 简单的 Java 对象,实际就是普通 JavaBeans,是为了避免和 EJB 混淆所创造的简称

2、通过控制反转 IoC、依赖注入 DI 和基于接口编程实现松耦合

3、通过 AOP 和默认惯例进行声明式编程

4、使用 AOP 和模板编程减少模式化代码

IoC/DI

IoC 控制反转。IoC 意味着将设计好的对象交给容器控制,而不是传统的在对象内部直接控制。IoC 是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。实际上真正的IoC 有两种实现方式 DI 依赖注入和 DL 依赖查找

DI 依赖注入即组件之间的依赖关系由容器在运行期决定,即由容器动态的将某种依赖关系注入到组件之中. 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。

依赖接口不依赖于实现:

public interface IUserDao {
    public void insert();
}
public class UserDaoImpl implements IUserDao{
    @Override
    public void insert() {
        System.out.println("执行数据库的插入操作!");
    }
}

上层调用:

public class UserServImpl {
//当前类需要依赖于 dao 层的具体实现执行数据的持久化操作        
    private IUserDao userDao;
    public void pp() {
        System.out.println("业务调用 DAO 开始");
        userDao.insert();
        System.out.println("业务调用 DAO 结束");
    }
}

DI 依赖注入

<bean id="userDao1" class="com.yan.dao.UserDaoImpl"/>
<bean id="userService" class="com.yan.biz.UserServImpl">
    <property name="userDao" ref="userDao1"/> 调用 setUserDao 方法将当前容器中的一个名称为
userDao1 的受管 bean 注入到 userService 对象中
bean>

实现过程:

开发过程就是定义对应的类,并进行配置,将对象纳入到容器中进行管理,即受管 bean。

bean 是 Spring 管理的基本单位,在 Spring 的应用中所有的组件都是 bean,bean 包括数据源、Hibernate 的SessionFactory 及事务管理器等。Spring 里的 bean 是非常广义的概念,任何的 Java 对象、Java 组件都可被当成 bean 处理。甚至这些组件并不是标准的 JavaBean

受管 bean 的配置方式有三种:1、在 Spring2.5-使用 xml 配置。2、xml+注解配置。3、Spring4.0+建议采用JavaConfig 类配置

一般情况下 Spring 通过反射机制利用的 class 属性指定实现类实例化 Bean

使用 xml 配置方式
<bean id="now" class="java.util.Date"/> 要求无参构造器
<bean id="df" class="java.text.SimpleDateFormat"> 要求带参数构造器
    <constructor-arg value="yyyy 年 M 月 d 日 E"/>
bean>
xml+注解

首先 spring 为了简化开发在 xml 配置文件中引入额外的命名空间 context,解决配置泥潭问题

Spring-1_第3张图片

自动创建出来的 xml 文件没有多余的名空间,只有一个默认名空间对应 beans


<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>

复制 beans 名空间就可以实现创建 context 名空间


<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">
beans>

打开自动组件扫描,在 com.yan 包及其子包中查找满足条件的类作为受管 bean

expression=“org.springframework.stereotype.Repository” />包含过滤条件,

type=annotaion 表示包含过滤条件为注解,如果一个类上有@Repository 注解则是受管 bean,没有则不是受管 bean;另外还有一个排除过滤条件 context:exclude-filter type=“” expression=“”/>

过滤条件的定义,其中对应的 type 有 5 种,要求大家熟悉的是 annotation

Spring-1_第4张图片

1、打开自动组件扫描

<context:component-scan base-package="com.yan.biz">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
context:component-scan>

2、定义对应的实现类,并添加对应的注解

@Component
public class UserDaoImpl implements IUserDao{
    @Override
    public void insert() {
        System.out.println("执行数据库的插入操作!");
    }
}

3、调用受管 bean

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
IUserDao userDao=ac.getBean(IUserDao.class);
userDao.insert();
Java Config 类

可以不使用 xml 配置文件

@Configuration // 用于声明当前类是一个配置类
public class MyConfig {
    @Bean // 用于声明返回值就是一个受管 bean,方法名称就是受管 bean 的 id
    public A1 aa() { return new A1(); }
}
ApplicationContext ac=new AnnotationConfigApplicationContext(MyConfig.class);
A1 aa=ac.getBean("aa", A1.class);

Bean 的创建方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean。

使用静态工厂实例化 bean

调用 DaoFactory 类中的静态方法 getUserDao 获取 userDao 对象,不是由 Spring 容器负责创建 userDao 对象

使用实例工厂方法:先创建 DaoFactrory 对象 userDaoFactory,然后获取 userDao 对象时,是通过调用userDaoFactory 对象的 getUserDao 方法获取

<bean id="userDaoFactory" class="com.ma.DAOFactory">bean>
<bean id=“userDao” factory-bean=“userDaoFactory” factory-method=“getUserDAO”/>

FactoryBean 创建对象的方法

FactoryBean 是 Spring 提供的一种整合第三方框架的常用机制,和普通的 bean 不同,配置一个 FactoryBean类型的 bean,在获取 bean 的时候得到的并不是 class 属性中配置的这个类的对象,而是 getObject()方法的返回值,通过这种机制,Spring 可以把复杂组件创建的详细过程和繁琐细节都屏蔽起来。例如在创建代码时可以代理来给接口来创建代理对象

public class MyFactoryBean<T> implements FactoryBean<T> {
    private final Class<T> clazz;
    public MyFactoryBean(Class<T> clazz) {
        this.clazz = clazz; }
    public T getObject() throws Exception { 获取对象
        return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), 
            new Class[]{clazz}, new MyFactoryBeanHandler()); }
    public Class<?> getObjectType() { 获取对象的类型
        return clazz; }
另外默认方法实现返回 boolean 表示是否为单例模式
}

当把 factorybean 的实现类配置为 bean 时,会将当前类中的 getObject 所返回的对象,交给 IoC 容器管理

编程调用

Resource r = new ClassPathResource(“applicationContext.xml”); 实现类 ClassPathResource 表示从 classpath中查找核心配置文件 applicationContext.xml,另外还有一个实现类为 FileSystemResource(“c:\beans.xml”)表示使用绝对路径查找对应的核心配置文件BeanFactory fac = new XmlBeanFactory®; 获取到 IoC 容器的引用,XmlBeanFactory 表示配置文件是 xml 文件,注意另外其他配置方法,不建议使用

Date now = (Date) fac.getBean(“now”); 通过受管 bean 的名称在容器中查找对应由容器创建的受管 bean 对象

System.out.println(now);

ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”); // 另 外 有 实 现 类

FileSystemXmlApplicationContext。ApplicationContext 接口继承于 BeanFactory 接口,主要用于引用 IoC/DI容器,ApplicationContext 具有 BeanFactory 的所有功能,另外提供针对企业级开发的功能支持

Date now=(Date)ac.getBean(“now”);

System.out.println(now);

BeanFactory & ApplicationContext [面试]

Spring 提供了两种类型的 IoC 容器实现,其中 BeanFactory 是 IoC 容器的基本实现,而 ApplicationContext提供了更多的高级特性,是 BeanFactory 的子接口。

针对单例类型的受管 bean,BeanFactory 默认采用延迟加载,ApplicationContext 默认采用立即加载BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;

ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory构建 BeanFactory 和 ApplicationContext 对象时实际上有 2 种不同的参数配置方法 FileSystem 和 ClassPath。

FileSystem 参数为具体的配置文件路径,ClassPath 是针对类路径的配置文件路径。在具体的产品应用开发中是没有办法设置具体路径,所以都是应用ClassPathXmlApplicationContext

scope 配置

scope 用于配置对象在 spring 容器中的生命周期或者对象在 spring 容器中的创建方式

scope 可以有参数选项有 5 种:默认singleton 单例,只创建一次,不管获取多少次只创建一次,prototype 原型模式,获取一次则创建一个对象,多实例,request/session/global session 用于 web 应用开发中,request 表示针对一个请求创建一个 user 对象,session 表示针对一个 session 创建一个 user 对象,global session 全局对象,表示针对一个应用创建一个对象

注解配置

@Component("user1") //声明受管 bean
@Scope("prototype")
public class User

一般不需要保持状态的对象,可以考虑使用单例;如果需要保持状态的对象,一般使用原型

你可能感兴趣的:(spring,java,hibernate)