SpringMVC---依赖注入与面向切面

1、依赖注入与面向切面

1.1、出现背景

——如何简化java开发?

       其中很重要的一点是“组件化”。

——如何更好的“组件化”?

       松耦合,以及尽可能的让组件专注于本身。

——Spring框架的目的也只有一个,就是简化java开发

 

1.2耦合

       很多框架通过强迫应用继承它们的类或实现它们的接口,从而让应用和框架绑死。而耦合又是必须的,有协作关系的类之间必定存在耦合,所以重要的是保持松散耦合

 

1.3、依赖注入DI(Dependency Injection)

       即利用第三方容器来管理类之间的耦合。在Spring中,对应的概念是Spring容器。它的设计思想主要是是反转资源获取的方向。

传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源。而应用了 IoC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源总结来说,Spring 就是一个实现了IoC的容器。

 

1.4、面向切面AOP(Aspect Oriented Programming)

(1)横切关注点:多个组件可能都需要用到的系统服务,如日志、事务管理(与组件核心业务逻辑无关)。

(2)双重复杂性:

 a. 横切关注点重复出现在多个组件中,修改和维护须修改各个模块相关实现。

 b. 组件因为这些与自身核心业务无关的代码而变得混乱。

(3)切点:定义了何处(在程序执行过程中的某个事件/方法)

(4)通知:定义了切面的事务,以及何时执行(相对于切点前后/环绕)

(5)切面:切面由通知和切点组成,它在何时何处完成什么功能

(6)连接点:连接点是一个应用执行过程中能够插入一个切面的点。

(7)织入: 织入是将切面应用到目标对象来创建的代理对象过程。

 

    仔细地观察上图,在程序执行过程中,可以有多个的连接点,在这些连接点上,我们便可以向其中插入切面(即你所想要插入的某个逻辑,这个逻辑,就是上面所说的横切关注点),这样我们就可以更好地理解下,什么是AOP?在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。

这样的思想有什么好处呢?试想一下,程序写好了之后,你想要针对所有业务操作添加一个日志,传统的做法是,改造每个业务方法,这样势必把代码弄得一团糟,而且以后再扩展还是更乱。而AOP的思想则是引导你从另一个切面来看待和插入这个日志,不管加在哪,它其实都是属于日志系统这个角度的。

举个例子:

       那么,这样说来,我们也就懂得为什么会有AOP的思想,殊途同归,就是为了降低我们维护和开发程序的开销,就是为了简化Java开发。

在这里,我们主要讲的是Spring的编程思想,理解这种思想后,再进行实际操作也会得心应手。

 

 

 

2、Bean的相关介绍

 

2.1、Bean的原理

        Bean就相当于定义一个组件,这个组件是用于具体实现某个功能的,可以重复使用。Bean的好处是:  

(1)可以不必再次编译,就可以工作在任何支持Java的平台上。  

(2)可以以其他组件模式工作。  

(3)可以在内部、网间和网内传输。  

 

2.2、什么是配置bean?

        Spring帮我们做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”,可以把Spring容器理解成一个大型工厂,Bean就是该工厂的产品,工厂(Spirng容器)里能生产出来什么样的产品(Bean),完全取决于我们在配置文件中的配置。

 

2.3、那么我们该如何配置Bean呢?

Bean的配置形式,主要有以下2种:

(1)基于 XML文件的方式

(2)基于注解的方式(这点在下文会有详细说明)

Bean的依赖注入方式,主要有以下3种:

(1)属性注入方法

(2)构造函数注入方法

(3)工厂方法注入方法

 

  • 属性注入方法:属性注入即通过setXXX()方法注入Bean的属性值或者依赖对象

  • 构造函数注入方法:构造函数注入方法保证一些必要的属性在Bean实例化时就得到了设置,并在实例化后就可以使用。

       【如果有多个构造器,可以通过index和value进行更加精确的定位】 

 

  • 工厂方法注入方法(静态工厂&实例工厂):即工厂类创建一个或多个工厂类实例,工厂类方法一般以接口或抽象类变量的形式返回目标类实例。不推荐使用。

 

2.4、 Bean的实例化

        在Spring IoC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化。Spring 提供了两种类型的 IoC 容器实现:

(1)Bean工厂 BeanFactory: IoC 容器的基本实现。

(2)应用上下文 ApplicationContext:提供了更多的高级特性,是BeanFactory 的子接口。

        BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身。而ApplicationContext面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用ApplicationContext,而非底层的 BeanFactory。无论使用何种方式, 配置文件是相同的。

我们看看下面的例子

        而Bean的实例化还有一种形式,即基于注解的形式,这在下文会提及,也是一种较为常用的方法。

 

2.5、Bean的自动装配

      自动装配(常用)定义是只声明Bean, 而把Bean之间的关系交给 IoC 容器来完成。Spring IoC 容器可以自动装配Bean,我们需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式。

(1)byType(根据类型自动装配): 若IoC容器中有多个与目标Bean类型一致的 bean,在这种情况下,Spring 将无法判定哪个 bean 最合适该属性,所以不能执行自动装配。

(2)byName(根据名称自动装配): 必须将目标Bean的名称和属性名设置的完全相同。

(3)constructor(通过构造器自动装配): 当Bean中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用。

(4)autodetect(自动检测):如果constructor装配失败,则采用byType。

 

2.6、基于注解配置bean

组件扫描(component scanning):  Spring 能够从 classpath 下自动扫描,侦测和实例化具有特定注解的组件。特定组件包括:

@Component: 基本注解, 标识了一个受 Spring 管理的组件

@Respository: 标识持久层组件

@Service: 标识服务层(业务层)组件

@Controller: 标识表现层组件

对于扫描到的组件, Spring 有默认的命名策略:使用非限定类名, 第一个字母小写,也可以在注解中通过 value 属性值标识组件的名称。

当在组件类上使用了特定的注解之后,还需要在 Spring 的配置文件中声明<context:component-scan>,其中base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类。就像这样:

Spring 还支持 @Resource 和 @Inject 注解,这两个注解和 @Autowired 注解的功用类似。@Resource 注解要求提供一个 bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 bean 的名称。@Inject 和 @Autowired 注解一样也是按类型匹配注入的 bean, 但没有 reqired 属性。建议读者使用@Autowired 注解。

当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注释时就找到和其匹配(默认按byType匹配)的 Bean,并注入到对应的地方中去。 

当然,该实例也可以自动装配具有@Resource 、@Inject注解的属性。它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。我们可以通过@Autowired的使用来消除 set ,get方法,如下图的例子:

2.7、Spring表达式语言:SpEL

Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。

语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL,SpEL 为bean 的属性进行动态赋值提供了便利。

通过 SpEL 可以实现:

       (1)通过bean 的 id 对 bean 进行引用

       (2)调用方法以及引用对象中的属性

       (3)计算表达式的值

       (4)正则表达式的匹配

 

2.8、Bean在Spring中的地位

其实 Spring 就是面向 Bean 的编程(BOP,Bean Oriented Programming),Bean 在 Spring 中才是真正的主角。

Bean 在 Spring 中作用就像 Object 对 OOP(Object OrientedProgramming) 的意义一样,没有对象的概念就像没有面向对象编程,Spring 中没有 Bean 也就没有 Spring 存在的意义。

    Bean的生命周期:

    (1)调用 Bean 的初始化方法,Bean 可以使用了

    (2)当容器关闭时, 会调用 Bean 的销毁方法 

 

 

3、SpringMVC调研流程

 

3.1、什么是Spring MVC

MVC实际上是一种设计模式

M代表model(模型)。模型表示企业数据和业务规则。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。

      V代表View(视图)。视图是用户看到并与之交互的界面。如html,jsp等。

      C代表Controller(控制器)。控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后用确定用哪个视图来显示模型处理返回的数据。

 

3.2、跟踪Spring MVC的请求

首先控制器接收到用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。

 

3.3、搭建Spring MVC

通过配置xml的形式

 

3.4、Spring MVC与数据库的结合

(1)DAO(数据访问对象)

        DAO提供了数据读取和写入到数据库中的一种方式,它们应该是以接口的方式发布功能。

可以通过Mybatis封装数据操作,如下面的例子,实现了IUserDao中的insert接口,参数类型为User,将User插入数据库User表中

(2)Service(服务对象)

       调用Dao的方法,实现我们所需要的操作,供Controller使用。

        一个经验:设计良好的控制器本身只处理很少甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象。

posted @ 2017-04-10 08:35  ATJAVA  阅读(4367)  评论(0编辑  收藏  举报