目录:
1、day01-Spring
2、day02-IOC和DI
3、day03-使用注解来简化配置
4、day04-SpringMVC
5、day05-系统分层(扩展)
6、day06-拦截器
1、day01-Spring
(1)Spring是什么?
是一个开源的,用来简化企业级应用开发的应用开发框架。
注:
a. Spring框架对常用的api做了封装(比如,对jdbc就做了封装),
这样一来,会简化代码并提高代码的质量(比如,使用SpringJdbc
来访问数据库,就不用再考虑如何获取连接与关闭连接等)。
b. Spring框架帮我们管理对象之间的依赖关系,这样一来,对象
之间的耦合度会大大降低,便于代码的维护。
c. Spring框架可以很方便地集成其它的一些框架。
(比如集成任务调度框架Quartz,集成MyBatis)。
(2)Spring容器
1)Spring容器是什么?
Spring框架中的一个核心模块,用于管理对象。
注:包括对象的创建、初始化、销毁以及对象之间的依赖关系的管理。
2)启动Spring容器
step1. 导包。(spring-webmvc)
点击主页寻找文件 已上传分享
step2. 添加Spring配置文件。(applicationContext.xml)
step3. 启动Spring容器。
3)创建对象
方式一 无参构造器
step1. 为类添加无参构造器(或者缺省构造器)。
step2. 修改配置文件,使用bean元素来配置。
step3. 启动容器,调用容器的getBean方法。
方式二 静态工厂方法 (了解)
方式三 实例工厂方法 (了解)
4)作用域
a.默认情况下,对于某个bean元素,容器只会创建一个实例。
b.如果将作用域设置为prototype,则容器会创建多个实例。
5)生命周期相关的两个方法
a. 初始化方法
b. 销毁方法
6)延迟加载(了解)
a.默认情况下,容器启动之后,会将所有作用域为singleton的bean
先实例化。
b.延迟加载(容器启动之后,即使作用域为单例,也不会创建其实例,
只有当调用getBean方法才会创建)。
2、day02-IOC和DI
(1)IOC是什么? (Inversion Of Controll 控制反转)
对象之间的依赖关系由容器来建立。
(2)DI是什么? (Dependency Injection 依赖注入)
容器通过调用set方法或者构造器来建立对象之间的依赖关系。
注:
IOC是目标,而DI是手段。
(3)set方法注入。
step1.添加相应的set方法。
step2.在配置文件中,使用property元素进行配置。
注:执行过程如下图:
(4)构造器注入
step1. 添加相应的构造器。
step2. 在配置文件当中,使用constructor-arg元素进行配置。
(5)自动装配(了解)
1)在配置文件当中,不用明确告诉容器采用哪种注入方式,也不用告诉
容器被注入的bean的id,由容器依据某些规则,自动建立对象之间的依赖
关系。
注:
a.容器仍然需要调用set方法或者构造器。
b.容器默认情况下,不会自动装配。
2)只需要配置autowire属性:
注:
a.自动装配要少用。(配置文件虽然简化了,但可读性变差,
另外,容易出错)
b.如果要使用自动装配,尽量使用byName。
(6)注入基本类型的值
使用value属性来注入。
(7)注入集合类型的值
1)可以注入List,Set,Map,Properties四种集合类型的值
2)方式一 直接注入
3)方式二 引用的方式注入
step1.先将集合类型的值配置成一个bean。
step2.使用ref注入这个bean。
(8)读取properties文件的内容
<util:properties id="" location=""/>
location用来指定properties文件的位置。
(9)Spring表达式
使用Spring表达式读取bean的属性
3、day03-使用注解来简化配置
(1)组件扫描
1)什么是组件扫描?
容器启动之后,会检查某个包及其子包下面的所有的类,如果该类
前面有特定的注解(比如@Component),则容器会将这个类纳入容器
进行管理(相当于在配置文件当中有一个bean元素)。
2)编程步骤
step1.在类前面添加一些注解。比如@Component
step2.在配置文件当中,添加组件扫描的配置。
(2)几个注解
1)指定作用域 @Scope(“值")
Scope:作用域 prototype:原型,可创建多个对象
singleton:单列,只可创建一个对象
2)指定生命周期的两个方法
@PostConstruct
@PreDestroy
3指定延迟加载(了解)
@Lazy(true)
(3)依赖注入相关的几个注解
1)Autowired和@Qualifier
a.支持set方法注入和构造器注入。
b.支持set方法注入时,可以将注解添加到set方法前,
并使用@Qualifier来指定被注入的bean的id。另外,
也可以将该注解直接添加到属性前。
c.支持构造器注入时,可以将该注解添加到构造器前面。
2)Resource
a.只支持set方法的注入。(该注解来自于sun)
b.将该注解添加到set方法前,或者也可以直接添加到属性前,
name属性用来指定被注入的bean的id。
(4)@Value
注入基本类型的值
注入Spring表达式的值
spring注解大全启用(2)
spring @component的作用
1、@controller 控制器(注入服务)
2、@service 服务(注入dao)
3、@repository dao(实现dao访问)
4、@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)
@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。
下面写这个是引入component的扫描组件
<context:component-scan base-package=”com.mmnc”>
其中base-package为需要扫描的包(含所有子包)
@Service
@Controller
@Repository
——————————————————————————————————————-
@Component
当组件不好归类的时候,我们可以使用这个注解进行标注。
——————————————————————————————————————-
@Scope("prototype/singleton”)
——————————————————————————————————————-
@Autowired
@Qualifier
——————————————————————————————————————-
@Resource
别是 name 和 type注释的 name 属性解析为 Bean 的名字,而 type
属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用
byName 的自动注入策略,而使用 type 属性时则使用 byType
自动注入策略。如果既不指定 name 也不指定 type 属性,这时将
通过反射机制使用 byName 自动注入策略。
——————————————————————————————————————-
@PostConstruct 生命周期的注解 初始化之后
@PreDestroy
——————————————————————————————————————-
@ResponseBody返回json或html指定格式
@Autowired与@Resource的区别
1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
Java代码
@Autowired() @Qualifier("baseDao")
private BaseDao baseDao;
3、@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定,
如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
Java代码
@Resource(name="baseDao")
private BaseDao baseDao;
在java代码中可以使用@Autowire或者@Resource注解方式进行装配,这两个注解的区别是:
@Autowire 默认按照类型装配,默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,如果我们想使用按照名称装配,可 以结合@Qualifier注解一起使用;
@Resource默认按照名称装配,当找不到与名称匹配的bean才会按照类型装配,可以通过name属性指定,如果没有指定name属 性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找 依赖对象.
各种注解方式
1.@Autowired注解(不推荐使用,建议使用@Resource)
@Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。@Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。要使@Autowired能够工作,还需要在配置文件中加入以下
Xml代码
1.
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
2. @Qualifier注解
@Autowired是根据类型进行自动装配的。例如,如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。如下:
1). 可能存在多个UserDao实例
Java代码
@Autowired
@Qualifier("userServiceImpl")
public IUserService userService;
或者
Java代码
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
这样,Spring会找到id为userServiceImpl和userDao的bean进行装配。
2). 可能不存在UserDao实例
Java代码
@Autowired(required = false)
public IUserService userService;
3. @Resource注解
JSR-250标准注解,推荐使用它来代替Spring专有的@Autowired注解。@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按byName自动注入罢了。@Resource有两个属性是比较重要的,分别是name和type,Spring将 @Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。要使@Autowired能够工作,还需要在配置文件中加入以下:
Xml代码
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
@Resource装配顺序:
a.如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
b.如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
c.如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
d.如果既没有指定name,又没有指定type,则自动按照byName方式进行装配(见2);如果没有匹配,则回退为一个原始类型(UserDao)进行匹配,如果匹配则自动装配;
4. @PostConstruct(JSR-250)注解
在方法上加上注解@PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行(注:Bean初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。它的一个典型的应用场景是,当你需要往Bean里注入一个其父类中定义的属性,而你又无法复写父类的属性或属性的setter方法时,如:
Java代码
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
private SessionFactory mySessionFacotry;
@Resource
public void setMySessionFacotry(SessionFactory sessionFacotry)
{
this.mySessionFacotry = sessionFacotry;
}
@PostConstruct
public void injectSessionFactory()
{
super.setSessionFactory(mySessionFacotry);
}
}
这里通过@PostConstruct,为UserDaoImpl的父类里定义的一个sessionFactory私有属性,注入了我们自己定义的 sessionFactory(父类的setSessionFactory方法为final,不可复写),之后我们就可以通过调用 super.getSessionFactory()来访问该属性了。
5. @PreDestroy(JSR-250)注解
在方法上加上注解@PreDestroy,这个方法就会在Bean初始化之后被Spring容器执行。其用法同@PostConstruct。和@PostConstruct 区别在于:@PostConstruct注释的方法将在类实例化后调用,而标注了 @PreDestroy 的方法将在类销毁之前调用。
6. @Component注解 (不推荐使用)
只需要在对应的类上加上一个@Component注解,就将该类定义为一个Bean了。Spring还提供了更加细化的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。目前版本(2.5)中,这些注解与@Component的语义是一样的,完全通用,在Spring以后的版本中可能会给它们追加更多的语义。所以,我们推荐使用@Repository、@Service、@Controller来替代@Component。
7.@Scope注解
在使用XML定义Bean时,我们可能还需要通过bean的scope属性来定义一个Bean的作用范围,我们同样可以通过@Scope注解来完成这项工作:
8. @ResponseBody
作用:
该注解用于将控制器的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,
写入到响应对象的体数据区。
使用时机:
返回的数据不是HTML标签的页面,而是其他某种格式的数据时(如JSON,XML等)使用;
@Scope("session")
@Component()
public class UserSessionBean implements Serializable{
... ...
}
二、配置启用注解(注意以下配置需要使用spring2.5的头文件,在spring3.0中不适用)
1.使用简化配置
Spring2.1添加了一个新的context的Schema命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。
AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor就是处理这些注释元数据的处理器。但是直接在Spring配置文件中定义这些Bean显得比较笨拙。Spring为我们提供了一种方便的注册这些BeanPostProcessor的方式,这就是,以下是spring的配置。
Xml代码
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
beans>
将隐式地向Spring容器注册了
AutowiredAnnotationBeanPostProcessor 、
CommonAnnotationBeanPostProcessor 、
PersistenceAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
这4个BeanPostProcessor。
2.使用让Bean定义注解工作起来
Xml代码
<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-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="com.kedacom.ksoa" />
beans>
这里,所有通过元素定义Bean的配置内容已经被移除,仅需要添加一行配置就解决所有问题了——Spring XML配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。的base-package属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
还允许定义过滤器将基包下的某些类纳入或排除。Spring支持以下4种类型的过滤方式:
过滤器类型 | 表达式范例 | 说明
注解 | org.example.SomeAnnotation | 将所有使用SomeAnnotation注解的类过滤出来
类名指定 | org.example.SomeClass | 过滤指定的类
正则表达式 | com\.kedacom\.spring\.annotation\.web\..* | 通过正则表达式过滤一些类
AspectJ表达式 | org.example..*Service+ | 通过AspectJ表达式过滤一些类
以正则表达式为例,我列举一个应用实例:
Xml代码
<context:component-scan base-package="com.casheen.spring.annotation">
<context:exclude-filter type="regex" expression="com\.casheen\.spring\.annotation\.web\..*" />
context:component-scan>
值得注意的是配置项不但启用了对类包进行扫描以实施注释驱动Bean定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor),因此当使用后,就可以将移除了。
3.
是不支持spring的@Transcation和EJB的Spring's @Transactional or EJB3's @TransactionAttribute annotation。用此配置可以达到目的。
4. 使用@Scope来定义Bean的作用范围
在使用XML定义Bean时,我们可能还需要通过bean的scope属性来定义一个Bean的作用范围,我们同样可以通过@Scope注解来完成这项工作:
Java代码
@Scope("session")
@Component()
public class UserSessionBean implements Serializable {
...
}
4、day04-SpringMVC
(1)MVC (Model View Controller)
1)MVC是什么?
是一种软件架构思想,其核心思想是将一个软件划分成三种不同类
型的模块,分别是模型,视图和控制器。其中,模型用来封装业务逻辑,
视图用来处理表示逻辑,控制器用来协调模型和视图(视图将请求先发送
给控制器,由控制器选择对应的模型来处理;模型返回的处理结果要先发
送给控制器,由控制器选择对应的视图来展现)。
2)如何使用MVC?
一般使用java类充当模型,使用Servlet充当控制器,使用
jsp充当视图。
3)优点?
a.方便测试
将业务逻辑写在java类里面,可以直接测试。
(如果将业务逻辑写在Servlet类里面,需要部署才能测试)。
b.模型发生变化,不影响视图;视图发生变化,也不影响模型。
(2)什么是SpringMVC?
用来简化基于MVC架构的web应用程序开发的框架。
注:SpringMVC是Spring框架的一个模块。
(3)SpringMVC的基本原理
1)DispatcherServlet 前端控制器
2)HandlerMapping 映射处理器
3)Controller 处理器
4)ModelAndView 处理结果
5)ViewResovler 视图解析器
step1.DispatcherServlet收到请求之后,依据HandlerMapping的
配置,调用Controller来处理。
step2.Controller将处理结果封装成ModelAndView,然后将该对象
返回给DispatcherServlet。
注:
字符串(比如"hello"),ViewResolver会将视图名解析成真正的
视图对象(比如hello.jsp)
视图技术有很多,比如jsp,FreeMarker,Velocity等等,
这样设计的好处:当需要使用新的视图技术的时候,只需要配置
新的ViewResolver即可。
step3.DispatcherServlet依据ViewResolver的解析,调用对应的jsp。
(4)在web.xml文件中配置spring
DispatcherServlet在初始化时会启动spring容器所以需要知道Spring配置文件的位置,
可以通过contextConfigLocation初始化参数来指定该位置。
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(5)在spring.xml中配置
HandlerMapping,Controller,ViewResolver
<!-- 配置HandlerMapping -->
<!--
告诉DispatcherServlet,请求路径与
Controller(处理器)的对应关系。
-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">helloController</prop>
</props>
</property>
</bean>
<!-- 配置Controller -->
<bean id=“helloController" class=" cn.tedu.spring.controller.HelloController"/>
<!-- 配置ViewResolver -->
<!-- 告诉DispatcherServlet,视图名对应的视图对象(比如某个jsp)。-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
(6)在 cn.tedu.spring.controller包下创建HelloController类并继承 Controller接口
5、day05-系统分层(扩展)
(1)如何分层?
表示层:数据展现和操作界面,请求分发。
业务层(服务层):封装业务逻辑。
数据访问层(持久层):封装数据访问逻辑。
(2)各层之间的关系。
1)表示层通过接口调用业务层的服务,业务层通过接口调用
数据访问层的服务。
2)下一层的实现发生任何改变,只要接口不变,不影响上一层。
练习: 使用SpringMVC完成员工列表,要求系统分层。
step1.导包。
spring-webmvc,ojdbc,dbcp,junit,jstl
step2.添加Spring配置文件
step3.配置DispatcherServlet
注:测试
step4.配置数据库连接池
config.properties
注:测试
step5.Employee类
step6.EmployeeDAO接口
public List<Employee> findAll();
step7.EmployeeDAOJdbcImpl类
注:测试持久层
step8. EmsService接口
public List<Employee> findAll();
step9. EmsServiceImpl类
注:测试业务层
step10. listEmp.jsp
step11. EmsController类
step12. 配置组件扫描,mvc注解扫描,视图解析器。
6、day06-拦截器
(1)什么是拦截器?
DispatcherServlet收到请求之后,如果有拦截器,则先执行
拦截器的方法,再执行处理器(Controller)的方法。
注:
过滤器属于Servlet规范,拦截的是Servlet容器调用过程,
而拦截器属于Spring框架,拦截的是DispatcherServlet的调用过程。
(2)如何写拦截器?
step1. 写一个java类,实现HandlerInterceptor接口。
step2. 在接口方法当中,实现拦截处理逻辑。
step3. 配置拦截器。
(3)拦截器的优先级
依据配置的先后顺序执行。
2.SpringMVC中的异常处理
注:可以将异常抛给Spring框架,由Spring框架来处理异常。
(1)配置简单异常处理器。
step1.配置简单异常处理器。
step2.添加异常处理页面。
(2)使用@ExceptionHandler注解
step1.在处理器类里面增加一个异常处理方法,
该方法前面需要添加@ExceptionHandler。
注:Spring框架捕获到异常之后,会调用异常处理方法。
step2.在异常处理方法里面,编写异常处理逻辑。
step3.添加异常处理页面。
3. SpringJdbc
(1)SpringJdbc是什么?
Spring框架对jdbc的封装。
(2)编程步骤
step1.导包。
spring-webmvc,ojdbc,dbcp,spring-jdbc,junit
step2.添加Spring配置文件。
step3.配置JdbcTemplate。
注:
JdbcTemplate对常用的jdbc api做了一些封装,调用这些
方法时,不再需要考虑如何获取连接、关闭连接以及处理异常等等。
step4.调用JdbcTemplate的方法来访问数据库。
注:
通常将JdbcTemplate注入到DAO。