spring以及spring MVC

一.spring的核心模块css

   Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了建立、配置和管理 bean 的方式,组成 Spring 框架的每一个模块(或组件)均可以单独存在,或者与其余一个或多个模块联合实现。每一个模块的功能以下:前端

       1)Spring Core:核心容器,BeanFactory提供了组件生命周期的管理,组件的建立,装配,销毁等功能java

    SpringContext:ApplicationContext,扩展核心容器,提供事件处理、国际化等功能。它提供了一些企业级服务的功能,提供了JNDI,EJB,RMI的支持。程序员

       2) Spring AOP:提供切面支持web

       3) Spring DAO:提供事务支持,JDBC,DAO支持spring

       4) Spring ORM:对流行的O/R Mapping封装或支持数据库

       5) Spring Web:提供Web应用上下文,对Web开发提供功能上的支持,如请求,表单,异常等。express

       6) Spring Web MVC:全功能MVC框架,做用等同于Struts。apache

     7)核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。编程

二.IOC的概念

控制反转(IOC):是面向对象编程中的一种设计原则,用来下降程序代码之间的耦合度,

         使整个程序体系结构更加灵活,与此同时将类的建立和依赖关系写在配置文件里,由配置文件注入,达到松耦合的效果。

         与此同时IOC也称为DI(依赖注入),依赖注入是一种开发模式;依赖注入提倡使用接口编程;

         依赖注入使得能够开发各个组件,而后根据组件之间的依赖关系注入组装。

2.2.IoC的类型

spring的注入方式:

      (1) 基于特定接口(侵入式方案)

      (2) 基于set方法:是容器经过调用无参构造器或无参static 工厂方法实列化bean以后,调用该bean的setter方法,    即实现了基于setter的依赖注入

      (3) 基于构造器:主要采用构造函数和构造器来进行注入

2.3.Spring容器

      Spring容器负责生成、组装、销毁组件,并负责事件处理、国际化等功能。

      (1) BeanFactory<interface>

        ① 核心容器,负责组件生成和装配

        ② 实现主要包括Xml BeanFactory

      (2) ApplicationContext

      (3) WebApplicationContext

      (4) ……

2.4IOC的使用

    Resource:interface,用来包装资源

    xmlBeanFactory:BeanFactory的一个实现,使用Resource对象来查找配置文件

    BeanFactory.gerBean(“BeanId”):取得以参数命名,或者Id等于参数值的一个Bean实例。

    BeanFactory(容器)在默认状况下,会采用单例方式返回对象。容器只到调用getBean方法时,才会实例化某个对象。

     (1) Spring能够采用XML或者.properties文件做配置

    (2) 配置文件(XML)

     根元素能够有多个子元素,每一个表明一个须要装配的对象。

public class HelloServiceTest {
    @Test
    public void testHelloWorld() {
        // 一、读取配置文件实例化一个IOC容器
        ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");
        // 二、从容器中获取Bean,注意此处彻底“面向接口编程,而不是面向实现”
        HelloService helloService = context.getBean("helloService", HelloService.class);
        // 三、执行业务逻辑
        helloService.sayHello();
    }
}

 

3、AOP核心概念

  一、Aspect(切面)

  切面,是对交叉业务逻辑的统称。

  二、Joinpoint(链接点)

  链接点,指切面能够织入到目标对象的位置(方法,属性等)。

  三、Advice(通知)

  通知,指切面的具体实现。

  四、Pointcut(切入点)

  切入点,指通知应用到哪些类的哪些方法或属性之上的规则。

  五、Introduction(引入)

  引入,指动态地给一个对象增长方法或属性的一种特殊的通知。

  六、Weaving(织入)

  织入,指将通知插入到目标对象。

  七、Target(目标对象)

  目标对象,指须要织入切面的对象。

  八、Proxy(代理对象)

  代理对象,指切面织入目标对象以后造成的对象。

3.1.AOP的原理 

    Spring AOP采用动态代理的过程:

(1) 将切面使用动态代理的方式动态织入到目标对象(被代理类),造成一个代理对象;

(2) 目标对象若是没有实现代理接口,那么Spring会采用CGLib来生成代理对象,该代理对象是目标对象的子类;

(3) 目标对象若是是final类,而且也没实现代理接口,就不能运用AOP。

  AOP编程实际上是很简单的事情,纵观AOP编程,程序员只须要参与三个部分:

一、定义普通业务组件

二、定义切入点,一个切入点可能横切多个业务组件

三、定义加强处理,加强处理就是在AOP框架为普通业务组件织入的处理动做

因此进行AOP编程的关键就是定义切入点和定义加强处理,一旦定义了合适的切入点和加强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=加强处理+被代理对象的方法。

基于Spring的AOP简单实现

注意一下,在讲解以前,说明一点:使用Spring AOP,要成功运行起代码,只用Spring提供给开发者的jar包是不够的,请额外上网下载两个jar包:

一、aopalliance.jar

二、aspectjweaver.jar

先定义一个接口:

public interface HelloWorld
{
    void printHelloWorld();
    void doPrint();
}

定义两个接口实现类:

public class HelloWorldImpl1 implements HelloWorld
{
    public void printHelloWorld()
    {
        System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
    }
    
    public void doPrint()
    {
        System.out.println("Enter HelloWorldImpl1.doPrint()");
        return ;
    }
}
public class HelloWorldImpl2 implements HelloWorld
{
    public void printHelloWorld()
    {
        System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
    }
    
    public void doPrint()
    {
        System.out.println("Enter HelloWorldImpl2.doPrint()");
        return ;
    }
}

横切关注点,这里是打印时间:

public class TimeHandler
{
    public void printTime()
    {
        System.out.println("CurrentTime = " + System.currentTimeMillis());
    }
}

有这三个类就能够实现一个简单的Spring AOP了,看一下aop.xml的配置:

<?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: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-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
        
        <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1" />
        <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" />
        <bean id="timeHandler" class="com.xrq.aop.TimeHandler" />
        
        <aop:config>
            <aop:aspect id="time" ref="timeHandler">
                <aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" />

<!--第一个*表示匹配任意的方法返回值,第二个*表示全部方法,..表示方法的任意参数个数-->

                <aop:before method="printTime" pointcut-ref="addAllMethod" />
                <aop:after method="printTime" pointcut-ref="addAllMethod" />
            </aop:aspect>
        </aop:config>
</beans>

使用一个main函数调用:

public static void main(String[] args)
{
    ApplicationContext ctx = 
            new ClassPathXmlApplicationContext("aop.xml");
        
    HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");
    HelloWorld hw2 = (HelloWorld)ctx.getBean("helloWorldImpl2");
    hw1.printHelloWorld();
    System.out.println();
    hw1.doPrint();
    
    System.out.println();
    hw2.printHelloWorld();
    System.out.println();
    hw2.doPrint();
}

运行结果为:

CurrentTime = 1446129611993
Enter HelloWorldImpl1.printHelloWorld()
CurrentTime = 1446129611993

CurrentTime = 1446129611994
Enter HelloWorldImpl1.doPrint()
CurrentTime = 1446129611994

CurrentTime = 1446129611994
Enter HelloWorldImpl2.printHelloWorld()
CurrentTime = 1446129611994

CurrentTime = 1446129611994
Enter HelloWorldImpl2.doPrint()
CurrentTime = 1446129611994

Spring注意事项

Spring的日志输出是依赖于commons-logging,可是spring的jar包中没有给咱们提供,因此咱们须要本身进行下载。

Spring最主要的核心包是4个【 beans、context、core、expression】,一个简单的spring须要着5个jar包便可,若是要扩展功能的话,咱们须要在源码的libs中再从新引入所须要的jar包。

Spring在链接数据库时,须要引入链接数据库的jar包,这个也须要咱们另外下载

四.spring MVC

4.1.SpringMVC流程

一、  用户发送请求至前端控制器DispatcherServlet。

二、  DispatcherServlet收到请求调用HandlerMapping处理器映射器。

三、  处理器映射器找到具体的处理器(能够根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(若是有则生成)一并返回给DispatcherServlet。

四、  DispatcherServlet调用HandlerAdapter处理器适配器。

五、  HandlerAdapter通过适配调用具体的处理器(Controller,也叫后端控制器)。

六、  Controller执行完成返回ModelAndView。

七、  HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

八、  DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

九、  ViewReslover解析后返回具体View。

十、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

十一、 DispatcherServlet响应用户。

4.2.组件:
一、前端控制器DispatcherServlet(不须要工程师开发),由框架提供
做用:接收请求,响应结果,至关于转发器,中央处理器。有了dispatcherServlet减小了其它组件之间的耦合度。
用户请求到达前端控制器,它就至关于mvc模式中的c,dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在下降了组件之间的耦合性。

二、处理器映射器HandlerMapping(不须要工程师开发),由框架提供
做用:根据请求的url查找Handler
HandlerMapping负责根据用户请求找到Handler即处理器,springmvc提供了不一样的映射器实现不一样的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

三、处理器适配器HandlerAdapter
做用:按照特定规则(HandlerAdapter要求的规则)去执行Handler
经过HandlerAdapter对处理器进行执行,这是适配器模式的应用,经过扩展适配器能够对更多类型的处理器进行执行。

四、处理器Handler(须要工程师开发)
注意:编写Handler时按照HandlerAdapter的要求去作,这样适配器才能够去正确执行Handler
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。
因为Handler涉及到具体的用户业务请求,因此通常状况须要工程师根据业务需求开发Handler。

五、视图解析器View resolver(不须要工程师开发),由框架提供
做用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果经过页面展现给用户。 springmvc框架提供了不少的View视图类型,包括:jstlView、freemarkerView、pdfView等。
通常状况下须要经过页面标签或页面模版技术将模型数据经过页面展现给用户,须要由工程师根据业务需求开发具体的页面。

六、视图View(须要工程师开发jsp...)
View是一个接口,实现类支持不一样的View类型(jsp、freemarker、pdf...)

4.3.springMVC-mvc.xml 配置文件片断讲解

<?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:tx="http://www.springframework.org/schema/tx"  
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:mvc="http://www.springframework.org/schema/mvc"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    http://www.springframework.org/schema/tx   
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
    http://www.springframework.org/schema/context  
    http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">  
  
  
    <!-- 自动扫描的包名 -->  
    <context:component-scan base-package="com.app,com.core,JUnit4" ></context:component-scan>  
      
    <!-- 默认的注解映射的支持 -->  
    <mvc:annotation-driven />  
      
    <!-- 视图解释类 -->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/jsp/"/>  
        <property name="suffix" value=".jsp"/><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑  -->  
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />  
    </bean>  
      
    <!-- 拦截器 -->  
    <mvc:interceptors>  
        <bean class="com.core.mvc.MyInteceptor" />  
    </mvc:interceptors>       
      
    <!-- 对静态资源文件的访问  方案一 (二选一) -->  
    <mvc:default-servlet-handler/>  
      
    <!-- 对静态资源文件的访问  方案二 (二选一)-->  
    <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>  
    <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/>  
    <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/>  
  
</beans>   

<context:component-scan/> 扫描指定的包中的类上的注解,经常使用的注解有:

@Controller 声明Action组件
@Service    声明Service组件    @Service("myMovieLister") 
@Repository 声明Dao组件
@Component   泛指组件, 当很差归类时. 
@RequestMapping("/menu")  请求映射
@Resource  用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName") 
@Autowired 用于注入,(srping提供的) 默认按类型装配 
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype")   设定bean的做用域

 

@ModelAtrribute的运行流程

1.执行@ModelAtrribute注解修饰的方法:从数据库中取出对象,并把对象放到了Map中,键为user

2.springMVC从Map集合中取出User对象,并把表单的请求参数赋值给user对象相应的属性

3.springMVC把上述对象传入目标方法的参数

4.这个user对象是存在request中,若是jsp表单中有对应的字段,还会自动填充表单

注意:在@ModelAtrribute修饰的方法中,放入Map时的键要和目标方法的参数名一致

 

4.4.Converter与Formatter

Spring的Converter能够将一种类型转换成另外一种类型。
在使用时,必须编写一个实现org.springframework.core.convert.converter.Converter接口的java类。这个接口的声明以下

public interface Converter<S, T> {
    T convert(S var1);
}

这里的S表示源类型,T表示目标类型。
下面展现了一个将String类型转换成Date类型的Converter

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class StringToDateConverter implements Converter<String, Date>{
    private static final Log logger = LogFactory.getLog(StringToDateConverter.class);
    private String datePattern;

    public StringToDateConverter(String datePattern) {
        this.datePattern = datePattern;
    }

    public Date convert(String s) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
            dateFormat.setLenient(false);
            return dateFormat.parse(s);
        } catch (ParseException e) {
            throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
        }
    }
}

为了使用Spring MVC应用程序定制的Converter,须要在配置文件中添加一个conversionService bean。Bean的类名称必须为org.springframework.context.support.ConversionServiceFactoryBean。这个bean必须包含一个converters属性,它列出要在应用程序中使用的全部定制Converter。下面bean声明注册了上面StringToDateConverter。

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="app06a.converter.StringToDateConverter">
                <constructor-arg name="datePattern" value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

以后,还须要给annotation-driven元素的conversion-service属性赋上bean名称,以下



2Formatter
Formatter和Converter同样,也是将一种类型转换成另外一种类型。可是,Formatter的源类型必须是一个String。
在使用时,必须编写一个实现org.springframework.format.Formatter接口的java类。这个接口的声明以下<mvc:annotation-driven conversion-service="conversionService"/>
public interface Formatter<T> extends Printer<T>, Parser<T> {
}
public interface Printer<T> {
    String print(T var1, Locale var2);
}
public interface Parser<T> {
    T parse(String var1, Locale var2) throws ParseException;
}

这里的T表示输入字符串要转换的目标类型。
parse方法利用指定的Locale将一个String解析成目标类型。print方法相反,它是返回目标对象的字符串表示法。
下面展现了一个将String类型转换成Date类型的Formatter

import org.springframework.format.Formatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class DateFormatter implements Formatter<Date>{
    private String datePattern;
    private SimpleDateFormat dateFormat;

    public DateFormatter(String datePattern) {
        this.dateFormat = dateFormat;
        dateFormat = new SimpleDateFormat(datePattern);
        dateFormat.setLenient(false);
    }
    public Date parse(String s, Locale locale) throws ParseException {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
            dateFormat.setLenient(false);
            return dateFormat.parse(s);
        } catch (ParseException e) {
            throw new IllegalArgumentException("invalid date format. Please use this pattern\"" + datePattern + "\"");
        }
    }

    public String print(Date date, Locale locale) {
        return dateFormat.format(date);
    }
}

为了使用Spring MVC应用程序定制的Formatter,须要在配置文件中添加一个conversionService bean。Bean的类名称必须为org.springframework.format.support.FormattingConversionServiceFactoryBean。这个bean能够用一个formatters属性注册Formatter,用一个converters属性注册Converter。下面bean声明注册了上面DateFormatter。

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="formatters">
        <set>
            <bean class="app06a.formatter.DateFormatter">
                <constructor-arg name="datePattern" value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

以后,还须要给annotation-driven元素的conversion-service属性赋上bean名称,以下

 
<mvc:annotation-driven conversion-service="conversionService"/>

3. 选择Converter仍是Formatter

Converter是通常工具,能够将一种类型转换成另外一种类型。例如,将String转换成Date,或者将Long转换成Date。Converter既能够用在web层,也能够用在其它层中。
Formatter只能将String转成成另外一种java类型。例如,将String转换成Date,但它不能将Long转换成Date。因此,Formatter适用于web层。为此,在Spring MVC应用程序中,选择Formatter比选择Converter更合适。

4.5.Validator

在要验证的的JavaBean中加入约束条件

在要进行验证的控制器参数前加上@Valid

 
 

4.6.Springmvc的优势

1.它是基于组件技术的.所有的应用对象,不管控制器和视图,仍是业务对象之类的都是 java组件.而且和Spring提供的其余基础结构紧密集成.

2.不依赖于Servlet API(目标虽是如此,可是在实现的时候确实是依赖于Servlet的)

3. 能够任意使用各类视图技术,而不只仅局限于JSP

4 .支持各类请求资源的映射策略

5 .它应是易于扩展的

相关文章
相关标签/搜索