【Spring第七篇】Java配置类:JavaConfig

Java配置类:JavaConfig


在spring配置中 applicationContext.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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

<!--    指定要扫描的包-->
    <context:component-scan base-package="com.kk"/>

    <!--    开启注解的支持-->
    <context:annotation-config/>


</beans>

@Configuration的作用

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

首先我在com.kk.config目录下创建一个自己的配置类 MyConfig

仔细阅读注解

  1. @Configuration类似于applicationContext.xml中的beans

  2. @Configuration 这个也会被Spring容器托管 注册到容器中 因为它本来就是一个@Component

  3. @Configuration 代表这是一个配置类,就和之前的beans.xml一样

/**
 * @Configuration类似于applicationContext.xml中的beans
 * @Configuration 这个也会被Spring容器托管 注册到容器中 因为它本来就是一个@Component
 * @Configuration 代表这是一个配置类,就和之前的beans.xml一样
 */
@Configuration
@ComponentScan("com.kk.pojo")
@Import(MyConfig_2.class)
public class MyConfig {
    /**
     * 注册一个bean,就相当于之前写的一个bean标签
     * 这个方法的名字(getUser)就相当于bean标签中的id
     *这个方法的返回值(User)就相当于bean标签中的class属性
     */
    @Bean
    public User getUser(){
        return new User();//就是返回要注入到bean的对象
    }

}

@Bean的作用

将这个类或者方法注册到spring IoC容器中,这个配置就等同于之前在xml里的配置

<beans>
    <bean id="getUser" class="com.kk.pojo.User"/>
</beans>
  1. 注册一个bean,就相当于之前写的一个bean标签

  2. 这个方法的名字(getUser)就相当于bean标签中的id

  3. 这个方法的返回值(User)就相当于bean标签中的class属性

    实际上是通过反射、代理来实现的

@componentscan的作用

@ComponentScan告诉Spring 哪个packages 用注解标识的类 ,会被spring自动扫描并且装入bean容器。

例如,如果你有个类用@Controller注解标识了,那么,如果不加上@ComponentScan,自动扫描该controller,那么该Controller就不会被spring扫描到,更不会装入spring容器中,因此你配置的这个Controller也没有意义。

@Import的作用

传入其他自定义配置类

@Configuration
public class MyConfig_2 {
}

测试:如果完全使用了配置类去做,就只能通过AnnotationConfig 上下文来获取容器,通过配置类的class对象加载

import com.kk.config.MyConfig;
import com.kk.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        //如果完全使用了配置类去做,就只能通过AnnotationConfig 上下文来获取容器,通过配置类的class对象加载
     ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

        User user = context.getBean("user", User.class);
        System.out.println(user.getName());

    }
}
 

@PropertySource(“db.properties”)

作用:用于在Java配置文件中读取resources目录下的db.properties文件

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8
user=root
password=123456

MyConfig.java

package com.kk.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.kk.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;


@SuppressWarnings("all")
@Configuration
@PropertySource("db.properties")
public class MyConfig {

    @Value("${drive}")
    private String driverClassName;
    @Value("${url}")
    private String url;
    @Value("${user}")
    private String username;
    @Value("${password}")
    private String password;

    @Bean
    public DruidDataSource getDruidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(driverClassName);
        druidDataSource.setUrl(url);
        druidDataSource.setUsername(username);
        druidDataSource.setPassword(password);
        return druidDataSource;
    }

}

测试:

package com.kk;
import com.kk.config.MyConfig;
import com.kk.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import javax.sql.DataSource;

/**
 * @author : k
 * @Date : 2022/4/9
 * @Desc :
 */
public class TestMyConfigDataSource {
    public static void main(String[] args) {

        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        DataSource bean = context.getBean(DataSource.class);
            System.out.println(bean);
    }
}

已经读取到配置文件db.properties的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4MRyLv3g-1649573493660)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20220409211305006.png)]

在这里插入图片描述

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE容器 1.3.1 容器服务 1.3.2 容器型 1.4 J2EE核心技术 1.4.1 Servlet 1.4.2 JSP(Java服务页面) 1.4.3 EJB(企业JavaBean) 1.4.4 JDBC(Java数据库连接) 1.4.5 JTA/JTS(Java事务) 1.4.6 JNDI(Java命名和目录服务) 1.4.7 JavaMail(Java邮件服务) 1.4.8 RMI(远程方法调用) 1.4.9 JMS(Java消息服务) 1.4.10 JMX(Java分布式管理) 1.4.11 JACC(Java容器授权合同) 1.4.12 JCA(Java连接器体系) 1.5 小结 第二章 MVC模式介绍 2.1 MVC模式概述 2.1.1 MVC模式的设计思想 2.1.2 MVC模式的处理过程 2.2 Model规范 2.2.1 Model1规范 2.2.2 Model2规范 2.3 使用MVC的优劣 2.3.1 使用MVC模式的好处 2.3.2 使用MVC模式的不足之处 2.4 目前市场上常见的轻量级J2EE开发容器 2.5 小结 第二篇 建立和使用J2EE的开发平台 第三章 建立Java的开发平台 3.1 建立Java的开发环境 3.1.1 下载JDK 3.1.2 安装JDK 3.1.3 设定Path、Classpath和JAVA_HOME 3.2 验证JDK是否安装成功 3.3 建立J2EE的开发环境 3.3.1 下载SDK 3.3.2 安装SDK 3.3.3 设定Path、Classpath和J2EE_HOME 3.4 小结 第四章 Tomcat使用指南 4.1 Tomcat简介 4.1.1 Tomcat的目录结构 4.1.2 Tomcat的配置参数 4.2 建立Tomcat的开发环境 4.2.1 下载Tomcat 4.2.2 设定TOMCAT_HOME 4.3 验证Tomcat是否安装成功 4.4 创建和发布Web应用 4.4.1 创建和发布JSP应用程序 4.4.2 创建和发布Servlet应用程序 4.5 小结 第五章 Eclipse使用指南 5.1 Eclipse简介 5.1.1 Eclipse的历史 5.1.2 Eclipse的运行机制 5.2 建立Eclipse的开发环境 5.2.1 下载Eclipse 5.2.2 配置Eclipse 5.3 整合Eclipse和Tomcat 5.3.1 下载Eclipse的Tomcat插件 5.3.2 为Eclipse配置Tomcat插件 5.4 使用Eclipse建立Web开发项目 5.5 Eclipse的常用快捷键 5.5.1 有关格式化的快捷键 5.5.2 有关调试的快捷键 5.5.3 有关重构的快捷键 5.6 小结 第六章 Log4j使用指南 6.1 Log4j介绍 6.1.1 Log4j历史 6.1.2 Log4j组成 6.2 建立Log4j的开发环境 6.2.1 下载Log4j 6.2.2 配置Log4j 6.3 Log4j的使用方法 6.3.1 配置Log4j 6.3.2 配置根Logger 6.3.3 指定日志输出位置 6.3.4 指定日志输出格式 6.3.5 指定日志输出优先级 6.3.6 在代码中使用Log4j 6.4 改进Log4j 6.5 小结 第七章 Ant使用指南 7.1 Ant介绍 7.1.1 Ant简介 7.1.2 为什么要使用Ant 7.2 建立Ant的开发环境 7.2.1 下载Ant 7.2.2 配置Ant 7.3 Ant的使用方法 7.3.1 Ant能完成的工作 7.3.2 配置文件build.xml 7.3.3 编译源代码 7.3.4 创建JAR文件 7.4 小结 第八章 JUnit使用指南 8.1 JUnit介绍 8.1.1 JUnit简介 8.1.2 为什么要使用JUnit 8.2 建立JUnit的开发环境 8.2.1 下载JUnit 8.2.2 配置JUnit 8.3 JUnit的使用方法 8.3.1 继承TestCase 8.3.2 编写测试方法 8.3.3 编写断言 8.4 JUnit的新特性 8.4.1 改变测试方法的命名方式 8.4.2 不再继承TestCase 8.4.3 改变初始化和销毁方式 8.4.4 改变异常处理的方式 8.5 小结 第九章 CVS使用指南 9.1 CVS介绍 9.1.1 CVS简介 9.1.2 为什么要使用CVS 9.2 建立CVS的开发环境 9.2.1 下载CVS 9.2.2 配置CVS 9.3 CVS的使用方法 9.3.1 添加CVS资源库 9.3.2 提交和更新代码 9.4 小结 第三篇 J2EE开发工具整合技术 第十章 使用Spring快速实现Web开发 10.1 Spring介绍 10.1.1 Spring简介 10.1.2 下载Spring 10.1.3 配置Spring 10.2 Spring核心思想 10.2.1 反向控制(IoC) 10.2.2 依赖注入(DI) 10.3 利用Spring在JSP页面输出“HelloWorld”的示例 10.3.1 建立myHelloWorld工程 10.3.2 编写JSP页面helloWorld.jsp 10.3.3 编写控制器HelloWorldController.java 10.3.4 建立Spring配置文档dispatcherServlet-servlet.xml 10.3.5 配置web.xml 10.3.6 启动Tomcat运行程序 10.4 Spring 的视图(View) 10.4.1 视图简介 10.4.2 视图解析 10.5 Spring的控制器(Controller) 10.5.1 Controller接口 10.5.2 命令控制器(BaseCommandController) 10.5.3 表单控制器(SimpleFormController) 10.5.4 多动作控制器(MultiActionController) 10.6 Spring的视图映射机制 10.6.1 分发器(DispatcherServlet) 10.6.2 视图映射 10.7 Spring的模型(Model) 10.7.1 模型简介 10.7.2 模型封装 10.8 小结 第十一章 使用Struts快速实现Web开发 11.1 Struts介绍 11.1.1 Struts简介 11.1.2 Struts和Spring比较 11.1.3 下载Struts 11.1.4 配置Struts 11.2 Struts的核心 11.2.1 ActionServlet(分发器) 11.2.2 Action(控制器) 11.2.3 Action Mapping(映射) 11.2.4 ActionForm(表单控制器) 11.2.5 ActionErrors(错误处理) 11.2.6 DispatchAction(多动作控制器) 11.3 利用Struts实现用户登录的示例 11.6.1 编写实现登录的页面login.jsp 11.6.2 编写存储登录用户信息的User.java 11.6.3 编写控制器LoginAction.java 11.6.4 配置Struts文档struts-config.xml 11.6.5 配置web.xml 11.6.6 启动Tomcat运行示例 11.4 整合Spring和Struts 11.4.1 Spring和Struts的整合方式 11.4.2 编写实现登录的页面regedit.jsp 11.4.3 编写存储登录用户信息的User.java 11.4.4 编写控制器RegeditAction.java 11.4.5 编写业务逻辑接口Regedit.java 11.4.6 编写具体的业务逻辑RegeditImpl.java 11.4.7 编写Struts的配置文件struts-config.xml 11.4.8 编写Spring配置文件spring-config.xml 11.4.9 配置web.xml 11.4.10 启动Tomcat运行示例 11.5 小结 第十二章 使用Hibernate快速实现持久层处理 12.1 Hibernate介绍 12.1.1 Hibernate简介 12.1.2 下载Hibernate 12.1.3 配置Hibernate 12.2 Hibernate的核心 12.2.1 Configuration(配置Connection) 12.2.2 SessionFactory(Connection工厂) 12.2.3 Session(提供Connection) 12.3 使用Hibernate操作数据库的示例 12.3.1 创建数据库表 12.3.2 编写表对应的JavaBean 12.3.3 编写JavaBean对应的Xml 12.3.4 编写Hibernate的配置文件 12.3.5 编写并验证测试程序 12.4 Hibernate的配置文件 12.4.1 Hibernate的两种配置方式 12.4.2 配置数据库连接池 12.4.3 使用JNDI 12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp 12.6.4 编写注册控制器RegeditAction.java 12.6.5 编写登录控制器LoginAction.java 12.6.6 建立数据库表 12.6.7 生成映射文件User.hbm.xml 12.6.8 生成POJO 12.6.9 编写注册的业务逻辑接口Regedit.java 12.6.10 编写注册的业务逻辑RegeditImpl.java 12.6.11 编写登录的业务逻辑接口Login.java 12.6.12 编写登录的业务逻辑LoginImpl.java 12.6.13 编写用户接口UserDAO.java 12.6.14 编写用户实现UserDAOImpl.java 12.6.15 编写Struts的配置文件struts-config.xml 12.6.16 编写Spring和Hibernate的配置文件spring-config.xml 12.6.17 编写web.xml 12.6.18 验证示例 12.7 小结 第四篇 J2EE项目案例精选 第十三章 网上调查系统 13.1 系统概述 13.2 需求分析 13.2.1 系统用例图 13.2.2 需求规格说明书 13.3 系统设计 13.3.1 设计视图层 13.3.2 设计持久层 13.3.3 设计业务逻辑层 13.3.4 设计控制层 13.4 架构设计和环境搭配 13.4.1 网上调查系统采用的架构 13.4.2 在Eclipse下建立项目mySurvey 13.4.3 编写本项目的Ant文件 13.4.4 配置本项目的web.xml文件 13.5 编写网上调查系统的JSP页面 13.5.1 用户注册画面regedit.jsp 13.5.2 用户登录画面login.jsp 13.5.3 设定调查题目的画面surveyName.jsp 13.5.4 设定调查项目的画面surveyOption.jsp 13.5.5 设定调查子项目的画面surveyChildOption.jsp 13.5.6 填写调查的画面survey.jsp 13.5.7 查看调查结果的画面surveyOK.jsp 13.6 根据数据库表生成XML和POJO 13.6.1 生成对应的XML 13.6.2 生成POJO 13.7 编写网上调查系统的DAO 13.7.1 用户DAO接口UserDAO.java 13.7.2 调查题目DAO接口SurveyDAO.java 13.7.3 调查项目DAO接口SurveyOptionDAO.java 13.7.4 调查子项目DAO接口SurveyChildDAO.java 13.7.5 调查结果DAO接口SurveyChildCountDAO.java 13.7.6 用户DAO实现UserDAOImpl.java 13.7.7 调查题目DAO实现SurveyDAOImpl.java 13.7.8 调查项目DAO实现SurveyOptionDAOImpl.java 13.7.9 调查子项目DAO实现SurveyChildDAOImpl.java 13.7.10 调查结果DAO实现SurveyChildCountDAOImpl.java 13.8 编写网上调查系统的业务逻辑 13.8.1 注册接口Regedit.java 13.8.2 登录接口Login.java 13.8.3 设定调查题目接口SetSurvey.java 13.8.4 设定调查项目接口SetSurveyOption.java 13.8.5 设定调查子项目接口SetSurveyChild.java 13.8.6 统计调查结果接口SetSurveyChildCount.java 13.8.7 注册实现RegeditImpl.java 13.8.8 登录实现LoginImpl.java 13.8.9 设定调查题目实现SetSurveyImpl.java 13.8.10 设定调查项目实现SetSurveyOptionImpl.java 13.8.11 设定调查子项目实现SetSurveyChildImpl.java 13.8.12 统计调查结果实现SetSurveyChildCountImpl.java 13.9 编写网上调查系统的控制器 13.9.1 登录控制器LoginAction.java 13.9.2 注册控制器RegeditAction.java 13.9.3 设定调查题目控制器SurveyAction.java 13.9.4 设定调查项目控制器SetSurveyAction.java 13.10 编写配置文件dispatcherServlet-servlet.xml 13.11 运行验证程序 13.12 小结 第十四章 内容管理系统 14.1 系统概述 14.2 需求分析 14.2.1 系统用例图 14.2.2 需求规格说明书 14.3 系统设计 14.3.1 设计视图层 14.3.2 设计持久层 14.3.3 设计业务逻辑层 14.3.4 设计控制层 14.4 架构设计和环境搭配 14.4.1 内容管理系统采用的架构 14.4.2 在Eclipse下建立项目myEdition 14.4.3 编写本项目的Ant文件 14.4.4 配置本项目的web.xml文件 14.5 编写内容管理系统的JSP页面 14.5.1 用户注册画面regedit.jsp 14.5.2 用户登录画面login.jsp 14.5.3 设定内容别画面type.jsp 14.5.4 发布内容画面edit.jsp 14.5.5 浏览内容画面index.jsp 14.6 根据数据库表生成XML和POJO 14.6.1 生成对应的XML 14.6.2 生成POJO 14.7 编写内容管理系统的DAO 14.7.1 用户DAO接口UserDAO.java 14.7.2 内容别DAO接口ContentTypeDAO.java 14.7.3 内容DAO接口ContentDAO.java 14.7.4 用户DAO实现UserDAOImpl.java 14.7.5 内容别DAO实现ContentTypeDAOImpl.java 14.7.6 内容DAO实现ContentDAOImpl.java 14.8 编写内容管理系统的业务逻辑 14.8.1 注册接口Regedit.java 14.8.2 登录接口Login.java 14.8.3 设定内容别的接口SetContentType.java 14.8.4 发布接口Edit.java 14.8.5 注册实现RegeditImpl.java 14.8.6 登录实现LoginImpl.java 14.8.7 设定内容别的实现SetContentTypeImpl.java 14.8.8 发布实现EditImpl.java 14.9 编写内容管理系统的控制器 14.9.1 登录控制器LoginAction.java 14.9.2 注册控制器RegeditAction.java 14.9.3 设定内容别的控制器ContentTypeAction.java 14.9.4 发布控制器EditAction.java 14.9.5 内容控制器ContentAction.java 14.9.6 浏览内容的控制器IndexAction.java 14.10 编写Struts的配置文件struts-config.xml 14.11 编写Spring和Hibernate的配置文件spring-config.xml 14.12 解决Struts的中文乱码问题 14.13 运行验证程序 14.14 小结 第十五章 在线考试系统 15.1 系统概述 15.2 需求分析 15.2.1 系统用例图 15.2.2 需求规格说明书 15.3 系统设计 15.3.1 设计视图层 15.3.2 设计持久层 15.3.3 设计业务逻辑层 15.3.4 设计控制层 15.4 架构设计和环境搭配 15.4.1 在线考试系统采用的架构 15.4.2 在Eclipse下建立项目myExam 15.4.3 编写本项目的Ant文件 15.4.4 配置本项目的web.xml文件 15.5 编写在线考试系统的JSP页面 15.5.1 用户注册画面regedit.jsp 15.5.2 用户登录画面login.jsp 15.5.3 设定试题种的画面shitiType.jsp 15.5.4 设定试题基本信息的画面shiti.jsp 15.5.5 设定试题项目的画面shitiOption.jsp 15.5.6 组织试卷的画面examInfo.jsp 15.5.7 参加考试的画面exam.jsp 15.5.8 考试成绩的画面examChengji.jsp 15.6 根据数据库表生成XML和POJO 15.6.1 生成对应的XML 15.6.2 生成POJO 15.7 编写在线考试系统的DAO 15.7.1 用户DAO接口UserDAO.java 15.7.2 试题种DAO接口ShitiTypeDAO.java 15.7.3 试题题目DAO接口ShitiDAO.java 15.7.4 试题项目DAO接口ShitiOptionDAO.java 15.7.5 试卷DAO接口ExamDAO.java 15.7.6 用户DAO实现UserDAOImpl.java 15.7.7 试题种DAO实现ShitiTypeDAOImpl.java 15.7.8 试题题目DAO实现ShitiDAOImpl.java 15.7.9 试题项目DAO实现ShitiOptionDAOImpl.java 15.7.10 试卷DAO实现ExamDAOImpl.java 15.8 编写在线考试系统的业务逻辑 15.8.1 注册接口Regedit.java 15.8.2 登录接口Login.java 15.8.3 设定试题种接口SetShitiType.java 15.8.4 设定试题题目接口SetShiti.java 15.8.5 设定试题项目接口SetShitiOption.java 15.8.6 设定试卷接口SetExam.java 15.8.7 注册实现RegeditImpl.java 15.8.8 登录实现LoginImpl.java 15.8.9 设定试题种实现SetShitiTypeImpl.java 15.8.10 设定试题题目实现SetShitiImpl.java 15.8.11 设定试题项目实现SetShitiOptionImpl.java 15.8.12 设定试卷实现SetExamImpl.java 15.9 编写在线考试系统的控制器 15.9.1 登录控制器LoginAction.java 15.9.2 注册控制器RegeditAction.java 15.9.3 设定试题种控制器ShitiTypeAction.java 15.9.4 设定试题题目控制器ShitiAction.java 15.9.5 设定试题项目控制器ShitiOptionAction.java 15.9.6 试卷控制器ExamAction.java 15.10 编写配置文件dispatcherServlet-servlet.xml 15.11 解决Spring的中文乱码问题 15.12 运行验证程序 15.13 小结
本书共分为两卷。 第1章 Spring简介 1 1.1 实例化Spring IoC容器 1 1.1.1 问题 1 1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 工作原理 14 1.4 解决构造程序歧义 17 1.4.1 问题 17 1.4.2 解决方案 17 1.4.3 工作原理 17 1.5 指定Bean引用 20 1.5.1 问题 20 1.5.2 解决方案 20 1.5.3 工作原理 20 1.6 为集合元素指定数据型 24 1.6.1 问题 24 1.6.2 解决方案 24 1.6.3 工作原理 24 1.7 使用Spring的FactoryBean创建Bean 27 1.7.1 问题 27 1.7.2 解决方案 27 1.7.3 工作原理 27 1.8 使用工厂Bean和Utility Schema定义集合 29 1.8.1 问题 29 1.8.2 解决方案 29 1.8.3 工作原理 29 1.9 用依赖检查属性 31 1.9.1 问题 31 1.9.2 解决方案 32 1.9.3 工作原理 32 1.10 用@Required注解检查属性 34 1.10.1 问题 34 1.10.2 解决方案 34 1.10.3 工作原理 34 1.11 用XML配置自动装配Bean 36 1.11.1 问题 36 1.11.2 解决方案 36 1.11.3 工作原理 37 1.12 用@Autowired和@Resource自动装配Bean 41 1.12.1 问题 41 1.12.2 解决方案 41 1.12.3 工作原理 41 1.13 继承Bean配置 47 1.13.1 问题 47 1.13.2 解决方案 47 1.13.3 工作原理 48 1.14 从Classpath中扫描组件 50 1.14.1 问题 50 1.14.2 解决方案 51 1.14.3 工作原理 51 1.15 小结 56 第2章 高级Spring IoC容器 57 2.1 调用静态工厂方法创建Bean 57 2.1.1 问题 57 2.1.2 解决方案 57 2.1.3 工作原理 57 2.2 调用一个实例工厂方法创建Bean 58 2.2.1 问题 58 2.2.2 解决方案 59 2.2.3 工作原理 59 2.3 从静态字段中声明Bean 60 2.3.1 问题 60 2.3.2 解决方案 60 2.3.3 工作原理 61 2.4 从对象属性中声明Bean 62 2.4.1 问题 62 2.4.2 解决方案 62 2.4.3 工作原理 62 2.5 使用Spring表达式语言 64 2.5.1 问题 64 2.5.2 解决方案 64 2.5.3 工作原理 65 2.6 设置Bean作用域 69 2.6.1 问题 69 2.6.2 解决方案 69 2.6.3 工作原理 70 2.7 自定义Bean初始化和析构 72 2.7.1 问题 72 2.7.2 解决方案 72 2.7.3 工作原理 72 2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 81 2.9.1 问题 81 2.9.2 解决方案 81 2.9.3 工作原理 82 2.10 加载外部资源 82 2.10.1 问题 82 2.10.2 解决方案 83 2.10.3 工作原理 83 2.11 创建Bean后处理器 85 2.11.1 问题 85 2.11.2 解决方案 85 2.11.3 工作原理 86 2.12 外部化Bean配置 89 2.12.1 问题 89 2.12.2 解决方案 89 2.12.3 工作原理 90 2.13 解析文本消息 91 2.13.1 问题 91 2.13.2 解决方案 91 2.13.3 工作原理 91 2.14 使用应用事件进行通信 93 2.14.1 问题 93 2.14.2 解决方案 93 2.14.3 工作原理 94 2.15 在Spring中注册属性编辑器 96 2.15.1 问题 96 2.15.2 解决方案 96 2.15.3 工作原理 97 2.16 创建自定义属性编辑器 99 2.16.1 问题 99 2.16.2 解决方案 100 2.16.3 工作原理 100 2.17 使用TaskExecutor实现并发性 101 2.17.1 问题 101 2.17.2 解决方案 101 2.17.3 工作原理 102 2.18 小结 110 第3章 Spring AOP和AspectJ支持 112 3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案 115 3.2.3 工作原理 116 3.3 访问连接点信息 121 3.3.1 问题 121 3.3.2 解决方案 122 3.3.3 工作原理 122 3.4 指定aspect优先级 123 3.4.1 问题 123 3.4.2 解决方案 123 3.4.3 工作原理 123 3.5 重用切入点定义 125 3.5.1 问题 125 3.5.2 解决方案 125 3.5.3 工作原理 125 3.6 编写AspectJ切入点表达式 127 3.6.1 问题 127 3.6.2 解决方案 127 3.6.3 工作原理 128 3.7 在你的Bean中引入行为 132 3.7.1 问题 132 3.7.2 解决方案 132 3.7.3 工作原理 132 3.8 为你的Bean引入状态 135 3.8.1 问题 135 3.8.2 解决方案 135 3.8.3 工作原理 135 3.9 用基于XML的配置声明aspect 137 3.9.1 问题 137 3.9.2 解决方案 137 3.9.3 工作原理 137 3.10 Spring中的AspectJ加载时织入aspect 140 3.10.1 问题 140 3.10.2 解决方案 141 3.10.3 工作原理 141 3.11 在Spring配置AspectJ aspect 146 3.11.1 问题 146 3.11.2 解决方案 146 3.11.3 工作原理 146 3.12 将Spring Bean注入领域对象 147 3.12.1 问题 147 3.12.2 解决方案 147 3.12.3 工作原理 148 3.13 小结 151 第4章 Spring中的脚本 152 4.1 用脚本语言实现Bean 152 4.1.1 问题 152 4.1.2 解决方案 153 4.1.3 工作原理 153 4.2 将Spring Bean注入脚本中 157 4.2.1 问题 157 4.2.2 解决方案 157 4.2.3 工作原理 157 4.3 从脚本中刷新Bean 160 4.3.1 问题 160 4.3.2 解决方案 160 4.3.3 工作原理 160 4.4 定义内联脚本源码 161 4.4.1 问题 161 4.4.2 解决方案 161 4.4.3 工作原理 161 4.5 小结 163 第5章 Spring Security 164 5.1 加强URL访问安全 165 5.1.1 问题 165 5.1.2 解决方案 165 5.1.3 工作原理 166 5.2 登录到Web应用 175 5.2.1 问题 175 5.2.2 解决方案 175 5.2.3 工作原理 175 5.3 验证用户 179 5.3.1 问题 179 5.3.2 解决方案 180 5.3.3 工作原理 180 5.4 做出访问控制决策 190 5.4.1 问题 190 5.4.2 解决方案 190 5.4.3 工作原理 191 5.5 加强方法调用的安全 193 5.5.1 问题 193 5.5.2 解决方案 193 5.5.3 工作原理 194 5.6 处理视图中的安全性 196 5.6.1 问题 196 5.6.2 解决方案 196 5.6.3 工作原理 196 5.7 处理领域对象安全性 198 5.7.1 问题 198 5.7.2 解决方案 198 5.7.3 工作原理 199 5.8 小结 208 第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR集成 232 6.5.1 问题 232 6.5.2 解决方案 232 6.5.3 工作原理 233 6.6 小结 236 第7章 Spring Web Flow 238 7.1 用Spring Web Flow管理简单的UI流程 238 7.1.1 问题 238 7.1.2 解决方案 239 7.1.3 工作原理 239 7.2 用不同状态型建立Web流程模型 246 7.2.1 问题 246 7.2.2 解决方案 246 7.2.3 工作原理 246 7.3 加强Web流程安全 257 7.3.1 问题 257 7.3.2 解决方案 258 7.3.3 工作原理 258 7.4 持续存储Web流程中的对象 260 7.4.1 问题 260 7.4.2 解决方案 260 7.4.3 工作原理 260 7.5 将Spring Web Flow与JSF集成 267 7.5.1 问题 267 7.5.2 解决方案 267 7.5.3 工作原理 267 7.6 使用RichFaces与Spring WebFlow协作 275 7.6.1 问题 275 7.6.2 解决方案 275 7.6.3 方法 275 7.7 小结 279 第8章 Spring @MVC 280 8.1 用Spring MVC开发简单的Web应用 280 8.1.1 问题 280 8.1.2 解决方案 281 8.1.3 工作原理 283 8.2 用@RequestMapping映射请求 293 8.2.1 问题 293 8.2.2 解决方案 294 8.2.3 工作原理 294 8.3 用处理程序拦截器拦截请求 297 8.3.1 问题 297 8.3.2 解决方案 298 8.3.3 工作原理 298 8.4 解析用户区域 302 8.4.1 问题 302 8.4.2 解决方案 302 8.4.3 工作原理 302 8.5 外部化区分区域的文本信息 304 8.5.1 问题 304 8.5.2 解决方案 304 8.5.3 工作原理 305 8.6 按照名称解析视图 306 8.6.1 问题 306 8.6.2 解决方案 306 8.6.3 工作原理 306 8.7 视图和内容协商 309 8.7.1 问题 309 8.7.2 解决方案 309 8.7.3 工作原理 309 8.8 映射异常视图 312 8.8.1 问题 312 8.8.2 解决方案 312 8.8.3 工作原理 312 8.9 用@Value在控制器中赋值 314 8.9.1 问题 314 8.9.2 解决方案 314 8.9.3 工作原理 314 8.10 用控制器处理表单 316 8.10.1 问题 316 8.10.2 解决方案 316 8.10.3 工作原理 317 8.11 用向导表单控制器处理多页表单 331 8.11.1 问题 331 8.11.2 解决方案 331 8.11.3 工作原理 332 8.12 使用注解(JSR-303)的Bean校验 341 8.12.1 问题 341 8.12.2 解决方案 342 8.12.3 工作原理 342 8.13 创建Excel和PDF视图 344 8.13.1 问题 344 8.13.2 解决方案 345 8.13.3 工作原理 345 8.14 小结 351 第9章 Spring REST 352 9.1 用Spring发布一个REST服务 352 9.1.1 问题 352 9.1.2 解决方案 353 9.1.3 工作原理 353 9.2 用Spring访问REST服务 358 9.2.1 问题 358 9.2.2 解决方案 358 9.2.3 工作原理 358 9.3 发布RSS和Atom信息源 362 9.3.1 问题 362 9.3.2 解决方案 363 9.3.3 工作原理 363 9.4 用REST服务发布JSON 372 9.4.1 问题 372 9.4.2 解决方案 372 9.4.3 工作原理 372 9.5 访问具有复杂XML响应的REST服务 375 9.5.1 问题 375 9.5.2 解决方案 375 9.5.3 工作原理 375 9.6 小结 385 第10章 Spring和Flex 386 10.1 Flex入门 388 10.1.1 问题 388 10.1.2 解决方案 388 10.1.3 工作原理 388 10.2 离开沙箱 393 10.2.1 问题 393 10.2.2 解决方案 394 10.2.3 工作原理 394 10.3 为应用添加Spring BlazeDS支持 406 10.3.1 问题 406 10.3.2 解决方案 406 10.3.3 工作原理 406 10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 411 10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用BlazeDS和Spring消费面向消息的服务 421 10.6.1 问题 421 10.6.2 解决方案 422 10.6.3 工作原理 422 10.7 将依赖注入带给你的ActionScript客户 434 10.7.1 问题 434 10.7.2 解决方案 434 10.7.3 工作原理 435 10.8 小结 439 第11章 Grails 441 11.1 获取和安装Grails 441 11.1.1 问题 441 11.1.2 解决方案 442 11.1.3 工作原理 442 11.2 创建Grails应用 443 11.2.1 问题 443 11.2.2 解决方案 443 11.2.3 工作原理 443 11.3 Grails插件 447 11.3.1 问题 447 11.3.2 解决方案 448 11.3.3 工作原理 448 11.4 在Grails环境中开发、生产和测试 449 11.4.1 问题 449 11.4.2 解决方案 449 11.4.3 工作原理 450 11.5 创建应用的领域 452 11.5.1 问题 452 11.5.2 解决方案 452 11.5.3 工作原理 452 11.6 为一个应用的领域生成CRUD控制器和视图 454 11.6.1 问题 454 11.6.2 解决方案 454 11.6.3 工作原理 455 11.7 国际化(I18n)信息属性 458 11.7.1 问题 458 11.7.2 解决方案 458 11.7.3 工作原理 458 11.8 改变永久性存储系统 461 11.8.1 问题 461 11.8.2 解决方案 461 11.4.3 工作原理 461 11.9 日志 464 11.9.1 问题 464 11.9.2 解决方案 464 11.9.3 工作原理 464 11.10 运行单元和集成测试 466 11.10.1 问题 466 11.10.2 解决方案 467 11.10.3 工作原理 467 11.11 使用自定义布局和模板 472 11.11.1 问题 472 11.11.2 解决方案 472 11.11.3 工作原理 472 11.12 使用GORM查询 475 11.12.1 问题 475 11.12.2 解决方案 475 11.12.3 工作原理 475 11.13 创建自定义标记 477 11.13.1 问题 477 11.13.2 解决方案 477 11.13.3 工作原理 478 11.14 小结 479 第12章 Spring Roo 481 12.1 设置Spring Roo开发环境 483 12.1.1 问题 483 12.1.2 解决方案 483 12.1.3 工作原理 483 12.2 创建第一个Spring Roo项目 486 12.2.1 问题 486 12.2.2 解决方案 486 12.2.3 工作原理 486 12.3 把现有项目导入SpringSource Tool Suite 491 12.3.1 问题 491 12.3.2 解决方案 492 12.3.3 工作原理 492 12.4 更快地构建更好的应用程序 493 12.4.1 问题 493 12.4.2 解决方案 494 12.4.3 工作原理 494 12.5 从项目中删除Spring Roo 500 12.5.1 问题 500 12.5.2 解决方案 500 12.5.3 工作原理 501 12.6 小结 502 第13章 Spring测试 503 13.1 用JUnit and TestNG创建测试 504 13.1.1 问题 504 13.1.2 解决方案 504 13.1.3 工作原理 504 13.2 创建单元测试和集成测试 509 13.2.1 问题 509 13.2.2 解决方案 509 13.2.3 工作原理 510 13.3 Spring MVC控制器的单元测试 518 13.3.1 问题 518 13.3.2 解决方案 518 13.3.3 工作原理 518 13.4 管理集成测试中的应用上下文 520 13.4.1 问题 520 13.4.2 解决方案 520 13.4.3 工作原理 521 13.5 向集成测试注入测试夹具 526 13.5.1 问题 526 13.5.2 解决方案 526 13.5.3 工作原理 527 13.6 管理集成测试中的事务 530 13.6.1 问题 530 13.6.2 解决方案 530 13.6.3 工作原理 531 13.7 在集成测试中访问数据库 536 13.7.1 问题 536 13.7.2 解决方案 536 13.7.3 工作原理 537 13.8 使用Spring的常用测试注解 540 13.8.1 问题 540 13.8.2 解决方案 540 13.8.3 工作原理 541 13.9 小结 542 第14章 Spring Portlet MVC框架 544 14.1 用Spring Portlet MVC开发一个简单的Portlet 544 14.1.1 问题 544 14.1.2 解决方案 545 14.1.3 工作原理 546 14.2 将Portlet请求映射到处理程序 553 14.2.1 问题 553 14.2.2 解决方案 553 14.2.3 工作原理 554 14.3 用简单的表单控制器处理portlet表单 561 14.3.1 问题 561 14.3.2 解决方案 561 14.3.3 工作原理 561 14.4 小结 569 第15章 数据访问 570 15.1 Direct JDBC的问题 571 15.1.1 建立应用数据库 571 15.1.2 理解数据访问对象设计模式 573 15.1.3 用JDBC实现DAO 573 15.1.4 在Spring配置数据源 575 15.1.5 运行DAO 577 15.1.6 更进一步 577 15.2 使用JDBC模板更新数据库 578 15.2.1 问题 578 15.2.2 解决方案 578 15.2.3 工作原理 578 15.3 使用JDBC模板查询数据库 583 15.3.1 问题 583 15.3.2 解决方案 583 15.3.3 工作原理 583 15.4 简化JDBC模板创建 588 15.4.1 问题 588 15.4.2 解决方案 588 15.4.3 工作原理 589 15.5 在Java 1.5中使用简单的JDBC模板 591 15.5.1 问题 591 15.5.2 解决方案 591 15.5.3 工作原理 591 15.6 在JDBC模板中使用命名参数 595 15.6.1 问题 595 15.6.2 解决方案 595 15.6.3 工作原理 595 15.7 在Spring JDBC框架中处理异常 597 15.7.1 问题 597 15.7.2 解决方案 597 15.7.3 工作原理 598 15.8 直接使用ORM框架的问题 602 15.8.1 问题 602 15.8.2 解决方案 603 15.8.3 工作原理 603 15.8.4 使用Hibernate API,用Hibernate XML映射持续化对象 604 15.8.5 使用Hibernate API,以JPA注解持续化对象 608 15.8.6 使用JPA,以Hibernate为引擎持续化对象 610 15.9 在Spring配置ORM资源工厂 613 15.9.1 问题 613 15.9.2 解决方案 614 15.9.3 工作原理 614 15.10 用Spring ORM模板持续化对象 620 15.10.1 问题 620 15.10.2 解决方案 620 15.10.3 工作原理 621 15.11 用Hibernate的上下文会话持续化对象 626 15.11.1 问题 626 15.11.2 解决方案 626 15.11.3 工作原理 626 15.12 用JPA的上下文注入持续化对象 629 15.12.1 问题 629 15.12.2 解决方案 629 15.12.3 工作原理 630 15.13 小结 632 第16章 Spring中的事务管理 634 16.1 事务管理的问题 635 16.2 选择一个事务管理器实现 641 16.2.1 问题 641 16.2.2 解决方案 641 16.2.3 工作原理 641 16.3 用事务管理器API编程管理事务 642 16.3.1 问题 642 16.3.2 解决方案 643 16.3.3 工作原理 643 16.4 用事务模板编程管理事务 644 16.4.1 问题 644 16.4.2 解决方案 645 16.4.3 工作原理 645 16.5 用事务通知声明式地管理事务 647 16.5.1 问题 647 16.5.2 解决方案 648 16.5.3 工作原理 648 16.6 用@Transactional注解声明式地管理事务 650 16.6.1 方法 650 16.6.2 解决方案 650 16.6.3 工作原理 650 16.7 设置事务传播属性 652 16.7.1 问题 652 16.7.2 解决方案 652 16.7.3 工作原理 653 16.8 设置隔离事务属性 657 16.8.1 问题 657 16.8.2 解决方案 657 16.8.3 工作原理 658 16.9 设置Rollback事务属性 664 16.9.1 问题 664 16.9.2 解决方案 664 16.9.3 工作原理 664 16.10 设置超时和只读事务属性 666 16.10.1 问题 666 16.10.2 解决方案 666 16.10.3 工作原理 666 16.11 用加载时织入管理事务 667 16.11.1 问题 667 16.11.2 解决方案 667 16.11.3 工作原理 667 16.12 小结 671 第17章 EJB、Spring Remoting和Web服务 672 17.1 通过RMI暴露和调用服务 672 17.1.1 问题 672 17.1.2 解决方案 673 17.1.3 工作原理 673 17.2 用Spring创建EJB 2.x组件 676 17.2.1 问题 676 17.2.2 解决方案 677 17.2.3 工作原理 677 17.3 在Spring中访问遗留的EJB 2.x组件 683 17.3.1 问题 683 17.3.2 解决方案 683 17.3.3 工作原理 684 17.4 在Spring中创建EJB 3.0组件 687 17.4.1 问题 687 17.4.2 解决方案 687 17.4.3 工作原理 688 17.5 在Spring中访问EJB 3.0组件 689 17.5.1 问题 689 17.5.2 解决方案 690 17.5.3 工作原理 690 17.6 通过HTTP暴露和调用服务 692 17.6.1 问题 692 17.6.2 解决方案 692 17.6.3 工作原理 692 17.7 选择SOAP Web服务开发方法 696 17.7.1 问题 696 17.7.2 解决方案 696 17.7.3 工作原理 696 17.8 使用JAX-WS暴露和调用Contract-Last SOAP Web服务 698 17.8.1 问题 698 17.8.2 解决方案 698 17.8.3 工作原理 698 17.9 定义Web服务契约 705 17.9.1 问题 705 17.9.2 解决方案 705 17.9.3 工作原理 705 17.10 使用Spring-WS实现Web服务 709 17.10.1 问题 709 17.10.2 解决方案 709 17.10.3 工作原理 710 17.11 使用Spring-WS调用Web服务 715 17.11.1 问题 715 17.11.2 解决方案 715 17.11.3 工作原理 715 17.12 用XML编组开发Web服务 719 17.12.1 问题 719 17.12.2 解决方案 719 17.12.3 工作原理 720 17.13 用注解创建服务端点 724 17.13.1 问题 724 17.13.2 解决方案 725 17.13.3 工作原理 725 17.14 小结 726 第18章 企业中的Spring 727 18.1 将Spring Bean输出为JMX MBean 727 18.1.1 问题 727 18.1.2 解决方案 728 18.1.3 工作原理 728 18.2 发布和监听JMX通知 740 18.2.1 问题 740 18.2.2 解决方案 740 18.2.3 工作原理 740 18.3 在Spring中访问远程JMX MBean 742 18.3.1 问题 742 18.3.2 解决方案 742 18.3.3 工作原理 742 18.4 用Spring电子邮件支持发送邮件 745 18.4.1 问题 745 18.4.2 解决方案 745 18.4.3 工作原理 746 18.5 用Spring的Quartz支持进行调度 753 18.5.1 问题 753 18.5.2 解决方案 753 18.5.3 工作原理 753 18.6 用Spring 3.0的调度命名空间进行调度 758 18.6.1 问题 758 18.6.2 解决方案 758 18.6.3 工作原理 758 18.7 小结 762 第19章 消息 763 19.1 用Spring发送和接收JMS消息 764 19.1.1 问题 764 19.1.2 解决方案 765 19.1.3 工作原理 765 19.2 转换JMS消息 776 19.2.1 问题 776 19.2.2 解决方案 776 19.2.3 方法 776 19.3 管理JMS事务 778 19.3.1 问题 778 19.3.2 方法 779 19.3.3 解决方案 779 19.4 在Spring中创建消息驱动POJO 780 19.4.1 问题 780 19.4.2 解决方案 780 19.4.3 工作原理 781 19.5 建立连接 786 19.5.1 问题 786 19.5.2 解决方案 787 19.5.3 工作原理 787 19.6 小结 788 第20章 Spring Integration 789 20.1 用EAI集成一个系统到另一个系统 790 20.1.1 问题 790 20.1.2 解决方案 790 20.1.3 工作原理 790 20.2 使用JMS集成两个系统 793 20.2.1 问题 793 20.2.2 解决方案 793 20.2.3 工作原理 793 20.3 查询Spring Integration消息得到上下文信息 797 20.3.1 问题 797 20.3.2 解决方案 797 20.3.3 工作原理 797 20.4 用一个文件系统集成两个系统 800 20.4.1 问题 800 20.4.2 解决方案 800 20.4.3 工作原理 800 20.5 将消息从一种型转换为另一种型 802 20.5.1 问题 802 20.5.2 解决方案 802 20.5.3 工作原理 803 20.6 使用Spring Integration进行错误处理 806 20.6.1 问题 806 20.6.2 解决方案 806 20.6.3 工作原理 806 20.7 集成控制分支:分解器和聚合器 809 20.7.1 问题 809 20.7.2 解决方案 809 20.7.3 工作原理 809 20.8 用路由器实现条件路由 813 20.8.1 问题 813 20.8.2 解决方案 813 20.8.3 工作原理 813 20.9 使外部系统适应总线 814 20.9.1 问题 814 20.9.2 解决方案 814 20.9.3 工作原理 814 20.10 用Spring Batch产生事件 825 20.10.1 问题 825 20.10.2 解决方案 825 20.10.3 工作原理 825 20.11 使用网关 826 20.11.1 问题 826 20.11.2 解决方案 826 20.11.3 工作原理 827 20.12 小结 832 第21章 Spring Batch 834 21.1 建立Spring Batch的基础架构 836 21.1.1 问题 836 21.1.2 解决方案 836 21.1.3 工作原理 837 21.2 读取和写入(无计算) 839 21.2.1 问题 839 21.2.2 解决方案 839 21.2.3 工作原理 840 21.3 编写自定义ItemWriter和ItemReader 844 21.3.1 问题 844 21.3.2 解决方案 844 21.3.3 工作原理 844 21.4 在写入前处理输入 847 21.4.1 问题 847 21.4.2 解决方案 847 21.4.3 工作原理 847 21.5 通过事务改善生活 850 21.5.1 问题 850 21.5.2 解决方案 850 21.5.3 工作原理 850 21.6 重试 852 21.6.1 问题 852 21.6.2 解决方案 852 21.6.3 工作原理 852 21.7 控制步骤异常 855 21.7.1 问题 855 21.7.2 解决方案 856 21.7.3 工作原理 856 21.8 启动一个作业 860 21.8.1 问题 860 21.8.2 解决方案 860 21.8.3 工作原理 860 21.9 参数化一个作业 864 21.9.1 问题 864 21.9.2 解决方案 864 21.9.3 工作原理 864 21.10 小结 866 第22章 网格上的Spring 867 22.1 使用Terracotta聚合对象状态 869 22.1.1 问题 869 22.1.2 解决方案 869 22.1.3 工作原理 869 22.2 将执行分布到网格上 879 22.2.1 问题 879 22.2.2 解决方案 879 22.2.3 方法 879 22.3 方法的负载平衡 880 22.3.1 问题 880 22.3.2 解决方案 881 22.3.3 方法 881 22.4 并行处理 884 22.4.1 问题 884 22.4.2 解决方案 885 22.4.3 方法 885 22.5 在GridGain上部署 887 22.5.1 问题 887 22.5.2 解决方案 887 22.5.3 工作原理 887 22.6 小结 891 第23章 jBPM和Spring 893 软件过程 894 23.1 理解工作流模型 896 23.1.1 问题 896 23.1.2 解决方案 897 23.1.3 工作原理 897 23.2 安装jBPM 898 23.2.1 问题 898 23.2.2 解决方案 898 23.2.3 工作原理 898 23.3 将jBPM4与Spring整合 900 23.3.1 问题 900 23.3.2 解决方案 900 23.3.3 工作原理 900 23.4 用Spring构建一个服务 906 23.4.1 问题 906 23.4.2 解决方案 906 23.4.3 工作原理 907 23.5 构建业务过程 910 23.5.1 问题 910 23.5.2 解决方案 910 23.5.3 工作原理 910 23.6 小结 913 第24章 OSGi和Spring 914 24.1 OSGi入门 915 24.1.1 问题 915 24.1.2 解决方案 915 24.1.3 工作原理 916 24.2 开始使用Spring Dynamic Modules 922 24.2.1 问题 922 24.2.2 解决方案 922 24.2.3 工作原理 922 24.3 用Spring Dynamic Modules输出服务 926 24.3.1 问题 926 24.3.2 解决方案 926 24.3.3 工作原理 926 24.4 在OSGi注册表中寻找一个具体服务 929 24.4.1 问题 929 24.4.2 解决方案 930 24.4.3 工作原理 930 24.5 发布多个接口的一个服务 932 24.5.1 问题 932 24.5.2 解决方案 932 24.5.3 工作原理 932 24.6 定制Spring Dynamic Modules 933 24.6.1 问题 933 24.6.2 解决方案 933 24.6.3 工作原理 933 24.7 使用SpringSource dm Server 935 24.7.1 问题 935 24.7.2 解决方案 935 24.7.3 工作原理 935 24.8 SpringSource的各工具 937 24.8.1 问题 937 24.8.2 解决方案 937 24.8.3 工作原理 937 24.9 小结 938 文摘 版权页:
本书共分为两卷。 第1章 Spring简介 1 1.1 实例化Spring IoC容器 1 1.1.1 问题 1 1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 工作原理 14 1.4 解决构造程序歧义 17 1.4.1 问题 17 1.4.2 解决方案 17 1.4.3 工作原理 17 1.5 指定Bean引用 20 1.5.1 问题 20 1.5.2 解决方案 20 1.5.3 工作原理 20 1.6 为集合元素指定数据型 24 1.6.1 问题 24 1.6.2 解决方案 24 1.6.3 工作原理 24 1.7 使用Spring的FactoryBean创建Bean 27 1.7.1 问题 27 1.7.2 解决方案 27 1.7.3 工作原理 27 1.8 使用工厂Bean和Utility Schema定义集合 29 1.8.1 问题 29 1.8.2 解决方案 29 1.8.3 工作原理 29 1.9 用依赖检查属性 31 1.9.1 问题 31 1.9.2 解决方案 32 1.9.3 工作原理 32 1.10 用@Required注解检查属性 34 1.10.1 问题 34 1.10.2 解决方案 34 1.10.3 工作原理 34 1.11 用XML配置自动装配Bean 36 1.11.1 问题 36 1.11.2 解决方案 36 1.11.3 工作原理 37 1.12 用@Autowired和@Resource自动装配Bean 41 1.12.1 问题 41 1.12.2 解决方案 41 1.12.3 工作原理 41 1.13 继承Bean配置 47 1.13.1 问题 47 1.13.2 解决方案 47 1.13.3 工作原理 48 1.14 从Classpath中扫描组件 50 1.14.1 问题 50 1.14.2 解决方案 51 1.14.3 工作原理 51 1.15 小结 56 第2章 高级Spring IoC容器 57 2.1 调用静态工厂方法创建Bean 57 2.1.1 问题 57 2.1.2 解决方案 57 2.1.3 工作原理 57 2.2 调用一个实例工厂方法创建Bean 58 2.2.1 问题 58 2.2.2 解决方案 59 2.2.3 工作原理 59 2.3 从静态字段中声明Bean 60 2.3.1 问题 60 2.3.2 解决方案 60 2.3.3 工作原理 61 2.4 从对象属性中声明Bean 62 2.4.1 问题 62 2.4.2 解决方案 62 2.4.3 工作原理 62 2.5 使用Spring表达式语言 64 2.5.1 问题 64 2.5.2 解决方案 64 2.5.3 工作原理 65 2.6 设置Bean作用域 69 2.6.1 问题 69 2.6.2 解决方案 69 2.6.3 工作原理 70 2.7 自定义Bean初始化和析构 72 2.7.1 问题 72 2.7.2 解决方案 72 2.7.3 工作原理 72 2.8 用Java Config简化XML配置 77 2.8.1 问题 77 2.8.2 解决方案 77 2.8.3 工作原理 77 2.9 使Bean感知容器 81 2.9.1 问题 81 2.9.2 解决方案 81 2.9.3 工作原理 82 2.10 加载外部资源 82 2.10.1 问题 82 2.10.2 解决方案 83 2.10.3 工作原理 83 2.11 创建Bean后处理器 85 2.11.1 问题 85 2.11.2 解决方案 85 2.11.3 工作原理 86 2.12 外部化Bean配置 89 2.12.1 问题 89 2.12.2 解决方案 89 2.12.3 工作原理 90 2.13 解析文本消息 91 2.13.1 问题 91 2.13.2 解决方案 91 2.13.3 工作原理 91 2.14 使用应用事件进行通信 93 2.14.1 问题 93 2.14.2 解决方案 93 2.14.3 工作原理 94 2.15 在Spring中注册属性编辑器 96 2.15.1 问题 96 2.15.2 解决方案 96 2.15.3 工作原理 97 2.16 创建自定义属性编辑器 99 2.16.1 问题 99 2.16.2 解决方案 100 2.16.3 工作原理 100 2.17 使用TaskExecutor实现并发性 101 2.17.1 问题 101 2.17.2 解决方案 101 2.17.3 工作原理 102 2.18 小结 110 第3章 Spring AOP和AspectJ支持 112 3.1 启用Spring的AspectJ注解支持 113 3.1.1 问题 113 3.1.2 解决方案 113 3.1.3 工作原理 113 3.2 用AspectJ注解声明aspect 115 3.2.1 问题 115 3.2.2 解决方案 115 3.2.3 工作原理 116 3.3 访问连接点信息 121 3.3.1 问题 121 3.3.2 解决方案 122 3.3.3 工作原理 122 3.4 指定aspect优先级 123 3.4.1 问题 123 3.4.2 解决方案 123 3.4.3 工作原理 123 3.5 重用切入点定义 125 3.5.1 问题 125 3.5.2 解决方案 125 3.5.3 工作原理 125 3.6 编写AspectJ切入点表达式 127 3.6.1 问题 127 3.6.2 解决方案 127 3.6.3 工作原理 128 3.7 在你的Bean中引入行为 132 3.7.1 问题 132 3.7.2 解决方案 132 3.7.3 工作原理 132 3.8 为你的Bean引入状态 135 3.8.1 问题 135 3.8.2 解决方案 135 3.8.3 工作原理 135 3.9 用基于XML的配置声明aspect 137 3.9.1 问题 137 3.9.2 解决方案 137 3.9.3 工作原理 137 3.10 Spring中的AspectJ加载时织入aspect 140 3.10.1 问题 140 3.10.2 解决方案 141 3.10.3 工作原理 141 3.11 在Spring配置AspectJ aspect 146 3.11.1 问题 146 3.11.2 解决方案 146 3.11.3 工作原理 146 3.12 将Spring Bean注入领域对象 147 3.12.1 问题 147 3.12.2 解决方案 147 3.12.3 工作原理 148 3.13 小结 151 第4章 Spring中的脚本 152 4.1 用脚本语言实现Bean 152 4.1.1 问题 152 4.1.2 解决方案 153 4.1.3 工作原理 153 4.2 将Spring Bean注入脚本中 157 4.2.1 问题 157 4.2.2 解决方案 157 4.2.3 工作原理 157 4.3 从脚本中刷新Bean 160 4.3.1 问题 160 4.3.2 解决方案 160 4.3.3 工作原理 160 4.4 定义内联脚本源码 161 4.4.1 问题 161 4.4.2 解决方案 161 4.4.3 工作原理 161 4.5 小结 163 第5章 Spring Security 164 5.1 加强URL访问安全 165 5.1.1 问题 165 5.1.2 解决方案 165 5.1.3 工作原理 166 5.2 登录到Web应用 175 5.2.1 问题 175 5.2.2 解决方案 175 5.2.3 工作原理 175 5.3 验证用户 179 5.3.1 问题 179 5.3.2 解决方案 180 5.3.3 工作原理 180 5.4 做出访问控制决策 190 5.4.1 问题 190 5.4.2 解决方案 190 5.4.3 工作原理 191 5.5 加强方法调用的安全 193 5.5.1 问题 193 5.5.2 解决方案 193 5.5.3 工作原理 194 5.6 处理视图中的安全性 196 5.6.1 问题 196 5.6.2 解决方案 196 5.6.3 工作原理 196 5.7 处理领域对象安全性 198 5.7.1 问题 198 5.7.2 解决方案 198 5.7.3 工作原理 199 5.8 小结 208 第6章 将Spring与其他Web框架集成 209 6.1 在一般Web应用中访问Spring 209 6.1.1 问题 209 6.1.2 解决方案 210 6.1.3 工作原理 210 6.2 在你的Servlet和过滤器中使用Spring 214 6.2.1 问题 214 6.2.2 解决方案 215 6.2.3 工作原理 215 6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR集成 232 6.5.1 问题 232 6.5.2 解决方案 232 6.5.3 工作原理 233 6.6 小结 236 第7章 Spring Web Flow 238 7.1 用Spring Web Flow管理简单的UI流程 238 7.1.1 问题 238 7.1.2 解决方案 239 7.1.3 工作原理 239 7.2 用不同状态型建立Web流程模型 246 7.2.1 问题 246 7.2.2 解决方案 246 7.2.3 工作原理 246 7.3 加强Web流程安全 257 7.3.1 问题 257 7.3.2 解决方案 258 7.3.3 工作原理 258 7.4 持续存储Web流程中的对象 260 7.4.1 问题 260 7.4.2 解决方案 260 7.4.3 工作原理 260 7.5 将Spring Web Flow与JSF集成 267 7.5.1 问题 267 7.5.2 解决方案 267 7.5.3 工作原理 267 7.6 使用RichFaces与Spring WebFlow协作 275 7.6.1 问题 275 7.6.2 解决方案 275 7.6.3 方法 275 7.7 小结 279 第8章 Spring @MVC 280 8.1 用Spring MVC开发简单的Web应用 280 8.1.1 问题 280 8.1.2 解决方案 281 8.1.3 工作原理 283 8.2 用@RequestMapping映射请求 293 8.2.1 问题 293 8.2.2 解决方案 294 8.2.3 工作原理 294 8.3 用处理程序拦截器拦截请求 297 8.3.1 问题 297 8.3.2 解决方案 298 8.3.3 工作原理 298 8.4 解析用户区域 302 8.4.1 问题 302 8.4.2 解决方案 302 8.4.3 工作原理 302 8.5 外部化区分区域的文本信息 304 8.5.1 问题 304 8.5.2 解决方案 304 8.5.3 工作原理 305 8.6 按照名称解析视图 306 8.6.1 问题 306 8.6.2 解决方案 306 8.6.3 工作原理 306 8.7 视图和内容协商 309 8.7.1 问题 309 8.7.2 解决方案 309 8.7.3 工作原理 309 8.8 映射异常视图 312 8.8.1 问题 312 8.8.2 解决方案 312 8.8.3 工作原理 312 8.9 用@Value在控制器中赋值 314 8.9.1 问题 314 8.9.2 解决方案 314 8.9.3 工作原理 314 8.10 用控制器处理表单 316 8.10.1 问题 316 8.10.2 解决方案 316 8.10.3 工作原理 317 8.11 用向导表单控制器处理多页表单 331 8.11.1 问题 331 8.11.2 解决方案 331 8.11.3 工作原理 332 8.12 使用注解(JSR-303)的Bean校验 341 8.12.1 问题 341 8.12.2 解决方案 342 8.12.3 工作原理 342 8.13 创建Excel和PDF视图 344 8.13.1 问题 344 8.13.2 解决方案 345 8.13.3 工作原理 345 8.14 小结 351 第9章 Spring REST 352 9.1 用Spring发布一个REST服务 352 9.1.1 问题 352 9.1.2 解决方案 353 9.1.3 工作原理 353 9.2 用Spring访问REST服务 358 9.2.1 问题 358 9.2.2 解决方案 358 9.2.3 工作原理 358 9.3 发布RSS和Atom信息源 362 9.3.1 问题 362 9.3.2 解决方案 363 9.3.3 工作原理 363 9.4 用REST服务发布JSON 372 9.4.1 问题 372 9.4.2 解决方案 372 9.4.3 工作原理 372 9.5 访问具有复杂XML响应的REST服务 375 9.5.1 问题 375 9.5.2 解决方案 375 9.5.3 工作原理 375 9.6 小结 385 第10章 Spring和Flex 386 10.1 Flex入门 388 10.1.1 问题 388 10.1.2 解决方案 388 10.1.3 工作原理 388 10.2 离开沙箱 393 10.2.1 问题 393 10.2.2 解决方案 394 10.2.3 工作原理 394 10.3 为应用添加Spring BlazeDS支持 406 10.3.1 问题 406 10.3.2 解决方案 406 10.3.3 工作原理 406 10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 411 10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用BlazeDS和Spring消费面向消息的服务 421 10.6.1 问题 421 10.6.2 解决方案 422 10.6.3 工作原理 422 10.7 将依赖注入带给你的ActionScript客户 434 10.7.1 问题 434 10.7.2 解决方案 434 10.7.3 工作原理 435 10.8 小结 439 第11章 Grails 441 11.1 获取和安装Grails 441 11.1.1 问题 441 11.1.2 解决方案 442 11.1.3 工作原理 442 11.2 创建Grails应用 443 11.2.1 问题 443 11.2.2 解决方案 443 11.2.3 工作原理 443 11.3 Grails插件 447 11.3.1 问题 447 11.3.2 解决方案 448 11.3.3 工作原理 448 11.4 在Grails环境中开发、生产和测试 449 11.4.1 问题 449 11.4.2 解决方案 449 11.4.3 工作原理 450 11.5 创建应用的领域 452 11.5.1 问题 452 11.5.2 解决方案 452 11.5.3 工作原理 452 11.6 为一个应用的领域生成CRUD控制器和视图 454 11.6.1 问题 454 11.6.2 解决方案 454 11.6.3 工作原理 455 11.7 国际化(I18n)信息属性 458 11.7.1 问题 458 11.7.2 解决方案 458 11.7.3 工作原理 458 11.8 改变永久性存储系统 461 11.8.1 问题 461 11.8.2 解决方案 461 11.4.3 工作原理 461 11.9 日志 464 11.9.1 问题 464 11.9.2 解决方案 464 11.9.3 工作原理 464 11.10 运行单元和集成测试 466 11.10.1 问题 466 11.10.2 解决方案 467 11.10.3 工作原理 467 11.11 使用自定义布局和模板 472 11.11.1 问题 472 11.11.2 解决方案 472 11.11.3 工作原理 472 11.12 使用GORM查询 475 11.12.1 问题 475 11.12.2 解决方案 475 11.12.3 工作原理 475 11.13 创建自定义标记 477 11.13.1 问题 477 11.13.2 解决方案 477 11.13.3 工作原理 478 11.14 小结 479 第12章 Spring Roo 481 12.1 设置Spring Roo开发环境 483 12.1.1 问题 483 12.1.2 解决方案 483 12.1.3 工作原理 483 12.2 创建第一个Spring Roo项目 486 12.2.1 问题 486 12.2.2 解决方案 486 12.2.3 工作原理 486 12.3 把现有项目导入SpringSource Tool Suite 491 12.3.1 问题 491 12.3.2 解决方案 492 12.3.3 工作原理 492 12.4 更快地构建更好的应用程序 493 12.4.1 问题 493 12.4.2 解决方案 494 12.4.3 工作原理 494 12.5 从项目中删除Spring Roo 500 12.5.1 问题 500 12.5.2 解决方案 500 12.5.3 工作原理 501 12.6 小结 502 第13章 Spring测试 503 13.1 用JUnit and TestNG创建测试 504 13.1.1 问题 504 13.1.2 解决方案 504 13.1.3 工作原理 504 13.2 创建单元测试和集成测试 509 13.2.1 问题 509 13.2.2 解决方案 509 13.2.3 工作原理 510 13.3 Spring MVC控制器的单元测试 518 13.3.1 问题 518 13.3.2 解决方案 518 13.3.3 工作原理 518 13.4 管理集成测试中的应用上下文 520 13.4.1 问题 520 13.4.2 解决方案 520 13.4.3 工作原理 521 13.5 向集成测试注入测试夹具 526 13.5.1 问题 526 13.5.2 解决方案 526 13.5.3 工作原理 527 13.6 管理集成测试中的事务 530 13.6.1 问题 530 13.6.2 解决方案 530 13.6.3 工作原理 531 13.7 在集成测试中访问数据库 536 13.7.1 问题 536 13.7.2 解决方案 536 13.7.3 工作原理 537 13.8 使用Spring的常用测试注解 540 13.8.1 问题 540 13.8.2 解决方案 540 13.8.3 工作原理 541 13.9 小结 542 第14章 Spring Portlet MVC框架 544 14.1 用Spring Portlet MVC开发一个简单的Portlet 544 14.1.1 问题 544 14.1.2 解决方案 545 14.1.3 工作原理 546 14.2 将Portlet请求映射到处理程序 553 14.2.1 问题 553 14.2.2 解决方案 553 14.2.3 工作原理 554 14.3 用简单的表单控制器处理portlet表单 561 14.3.1 问题 561 14.3.2 解决方案 561 14.3.3 工作原理 561 14.4 小结 569 第15章 数据访问 570 15.1 Direct JDBC的问题 571 15.1.1 建立应用数据库 571 15.1.2 理解数据访问对象设计模式 573 15.1.3 用JDBC实现DAO 573 15.1.4 在Spring配置数据源 575 15.1.5 运行DAO 577 15.1.6 更进一步 577 15.2 使用JDBC模板更新数据库 578 15.2.1 问题 578 15.2.2 解决方案 578 15.2.3 工作原理 578 15.3 使用JDBC模板查询数据库 583 15.3.1 问题 583 15.3.2 解决方案 583 15.3.3 工作原理 583 15.4 简化JDBC模板创建 588 15.4.1 问题 588 15.4.2 解决方案 588 15.4.3 工作原理 589 15.5 在Java 1.5中使用简单的JDBC模板 591 15.5.1 问题 591 15.5.2 解决方案 591 15.5.3 工作原理 591 15.6 在JDBC模板中使用命名参数 595 15.6.1 问题 595 15.6.2 解决方案 595 15.6.3 工作原理 595 15.7 在Spring JDBC框架中处理异常 597 15.7.1 问题 597 15.7.2 解决方案 597 15.7.3 工作原理 598 15.8 直接使用ORM框架的问题 602 15.8.1 问题 602 15.8.2 解决方案 603 15.8.3 工作原理 603 15.8.4 使用Hibernate API,用Hibernate XML映射持续化对象 604 15.8.5 使用Hibernate API,以JPA注解持续化对象 608 15.8.6 使用JPA,以Hibernate为引擎持续化对象 610 15.9 在Spring配置ORM资源工厂 613 15.9.1 问题 613 15.9.2 解决方案 614 15.9.3 工作原理 614 15.10 用Spring ORM模板持续化对象 620 15.10.1 问题 620 15.10.2 解决方案 620 15.10.3 工作原理 621 15.11 用Hibernate的上下文会话持续化对象 626 15.11.1 问题 626 15.11.2 解决方案 626 15.11.3 工作原理 626 15.12 用JPA的上下文注入持续化对象 629 15.12.1 问题 629 15.12.2 解决方案 629 15.12.3 工作原理 630 15.13 小结 632 第16章 Spring中的事务管理 634 16.1 事务管理的问题 635 16.2 选择一个事务管理器实现 641 16.2.1 问题 641 16.2.2 解决方案 641 16.2.3 工作原理 641 16.3 用事务管理器API编程管理事务 642 16.3.1 问题 642 16.3.2 解决方案 643 16.3.3 工作原理 643 16.4 用事务模板编程管理事务 644 16.4.1 问题 644 16.4.2 解决方案 645 16.4.3 工作原理 645 16.5 用事务通知声明式地管理事务 647 16.5.1 问题 647 16.5.2 解决方案 648 16.5.3 工作原理 648 16.6 用@Transactional注解声明式地管理事务 650 16.6.1 方法 650 16.6.2 解决方案 650 16.6.3 工作原理 650 16.7 设置事务传播属性 652 16.7.1 问题 652 16.7.2 解决方案 652 16.7.3 工作原理 653 16.8 设置隔离事务属性 657 16.8.1 问题 657 16.8.2 解决方案 657 16.8.3 工作原理 658 16.9 设置Rollback事务属性 664 16.9.1 问题 664 16.9.2 解决方案 664 16.9.3 工作原理 664 16.10 设置超时和只读事务属性 666 16.10.1 问题 666 16.10.2 解决方案 666 16.10.3 工作原理 666 16.11 用加载时织入管理事务 667 16.11.1 问题 667 16.11.2 解决方案 667 16.11.3 工作原理 667 16.12 小结 671 第17章 EJB、Spring Remoting和Web服务 672 17.1 通过RMI暴露和调用服务 672 17.1.1 问题 672 17.1.2 解决方案 673 17.1.3 工作原理 673 17.2 用Spring创建EJB 2.x组件 676 17.2.1 问题 676 17.2.2 解决方案 677 17.2.3 工作原理 677 17.3 在Spring中访问遗留的EJB 2.x组件 683 17.3.1 问题 683 17.3.2 解决方案 683 17.3.3 工作原理 684 17.4 在Spring中创建EJB 3.0组件 687 17.4.1 问题 687 17.4.2 解决方案 687 17.4.3 工作原理 688 17.5 在Spring中访问EJB 3.0组件 689 17.5.1 问题 689 17.5.2 解决方案 690 17.5.3 工作原理 690 17.6 通过HTTP暴露和调用服务 692 17.6.1 问题 692 17.6.2 解决方案 692 17.6.3 工作原理 692 17.7 选择SOAP Web服务开发方法 696 17.7.1 问题 696 17.7.2 解决方案 696 17.7.3 工作原理 696 17.8 使用JAX-WS暴露和调用Contract-Last SOAP Web服务 698 17.8.1 问题 698 17.8.2 解决方案 698 17.8.3 工作原理 698 17.9 定义Web服务契约 705 17.9.1 问题 705 17.9.2 解决方案 705 17.9.3 工作原理 705 17.10 使用Spring-WS实现Web服务 709 17.10.1 问题 709 17.10.2 解决方案 709 17.10.3 工作原理 710 17.11 使用Spring-WS调用Web服务 715 17.11.1 问题 715 17.11.2 解决方案 715 17.11.3 工作原理 715 17.12 用XML编组开发Web服务 719 17.12.1 问题 719 17.12.2 解决方案 719 17.12.3 工作原理 720 17.13 用注解创建服务端点 724 17.13.1 问题 724 17.13.2 解决方案 725 17.13.3 工作原理 725 17.14 小结 726 第18章 企业中的Spring 727 18.1 将Spring Bean输出为JMX MBean 727 18.1.1 问题 727 18.1.2 解决方案 728 18.1.3 工作原理 728 18.2 发布和监听JMX通知 740 18.2.1 问题 740 18.2.2 解决方案 740 18.2.3 工作原理 740 18.3 在Spring中访问远程JMX MBean 742 18.3.1 问题 742 18.3.2 解决方案 742 18.3.3 工作原理 742 18.4 用Spring电子邮件支持发送邮件 745 18.4.1 问题 745 18.4.2 解决方案 745 18.4.3 工作原理 746 18.5 用Spring的Quartz支持进行调度 753 18.5.1 问题 753 18.5.2 解决方案 753 18.5.3 工作原理 753 18.6 用Spring 3.0的调度命名空间进行调度 758 18.6.1 问题 758 18.6.2 解决方案 758 18.6.3 工作原理 758 18.7 小结 762 第19章 消息 763 19.1 用Spring发送和接收JMS消息 764 19.1.1 问题 764 19.1.2 解决方案 765 19.1.3 工作原理 765 19.2 转换JMS消息 776 19.2.1 问题 776 19.2.2 解决方案 776 19.2.3 方法 776 19.3 管理JMS事务 778 19.3.1 问题 778 19.3.2 方法 779 19.3.3 解决方案 779 19.4 在Spring中创建消息驱动POJO 780 19.4.1 问题 780 19.4.2 解决方案 780 19.4.3 工作原理 781 19.5 建立连接 786 19.5.1 问题 786 19.5.2 解决方案 787 19.5.3 工作原理 787 19.6 小结 788 第20章 Spring Integration 789 20.1 用EAI集成一个系统到另一个系统 790 20.1.1 问题 790 20.1.2 解决方案 790 20.1.3 工作原理 790 20.2 使用JMS集成两个系统 793 20.2.1 问题 793 20.2.2 解决方案 793 20.2.3 工作原理 793 20.3 查询Spring Integration消息得到上下文信息 797 20.3.1 问题 797 20.3.2 解决方案 797 20.3.3 工作原理 797 20.4 用一个文件系统集成两个系统 800 20.4.1 问题 800 20.4.2 解决方案 800 20.4.3 工作原理 800 20.5 将消息从一种型转换为另一种型 802 20.5.1 问题 802 20.5.2 解决方案 802 20.5.3 工作原理 803 20.6 使用Spring Integration进行错误处理 806 20.6.1 问题 806 20.6.2 解决方案 806 20.6.3 工作原理 806 20.7 集成控制分支:分解器和聚合器 809 20.7.1 问题 809 20.7.2 解决方案 809 20.7.3 工作原理 809 20.8 用路由器实现条件路由 813 20.8.1 问题 813 20.8.2 解决方案 813 20.8.3 工作原理 813 20.9 使外部系统适应总线 814 20.9.1 问题 814 20.9.2 解决方案 814 20.9.3 工作原理 814 20.10 用Spring Batch产生事件 825 20.10.1 问题 825 20.10.2 解决方案 825 20.10.3 工作原理 825 20.11 使用网关 826 20.11.1 问题 826 20.11.2 解决方案 826 20.11.3 工作原理 827 20.12 小结 832 第21章 Spring Batch 834 21.1 建立Spring Batch的基础架构 836 21.1.1 问题 836 21.1.2 解决方案 836 21.1.3 工作原理 837 21.2 读取和写入(无计算) 839 21.2.1 问题 839 21.2.2 解决方案 839 21.2.3 工作原理 840 21.3 编写自定义ItemWriter和ItemReader 844 21.3.1 问题 844 21.3.2 解决方案 844 21.3.3 工作原理 844 21.4 在写入前处理输入 847 21.4.1 问题 847 21.4.2 解决方案 847 21.4.3 工作原理 847 21.5 通过事务改善生活 850 21.5.1 问题 850 21.5.2 解决方案 850 21.5.3 工作原理 850 21.6 重试 852 21.6.1 问题 852 21.6.2 解决方案 852 21.6.3 工作原理 852 21.7 控制步骤异常 855 21.7.1 问题 855 21.7.2 解决方案 856 21.7.3 工作原理 856 21.8 启动一个作业 860 21.8.1 问题 860 21.8.2 解决方案 860 21.8.3 工作原理 860 21.9 参数化一个作业 864 21.9.1 问题 864 21.9.2 解决方案 864 21.9.3 工作原理 864 21.10 小结 866 第22章 网格上的Spring 867 22.1 使用Terracotta聚合对象状态 869 22.1.1 问题 869 22.1.2 解决方案 869 22.1.3 工作原理 869 22.2 将执行分布到网格上 879 22.2.1 问题 879 22.2.2 解决方案 879 22.2.3 方法 879 22.3 方法的负载平衡 880 22.3.1 问题 880 22.3.2 解决方案 881 22.3.3 方法 881 22.4 并行处理 884 22.4.1 问题 884 22.4.2 解决方案 885 22.4.3 方法 885 22.5 在GridGain上部署 887 22.5.1 问题 887 22.5.2 解决方案 887 22.5.3 工作原理 887 22.6 小结 891 第23章 jBPM和Spring 893 软件过程 894 23.1 理解工作流模型 896 23.1.1 问题 896 23.1.2 解决方案 897 23.1.3 工作原理 897 23.2 安装jBPM 898 23.2.1 问题 898 23.2.2 解决方案 898 23.2.3 工作原理 898 23.3 将jBPM4与Spring整合 900 23.3.1 问题 900 23.3.2 解决方案 900 23.3.3 工作原理 900 23.4 用Spring构建一个服务 906 23.4.1 问题 906 23.4.2 解决方案 906 23.4.3 工作原理 907 23.5 构建业务过程 910 23.5.1 问题 910 23.5.2 解决方案 910 23.5.3 工作原理 910 23.6 小结 913 第24章 OSGi和Spring 914 24.1 OSGi入门 915 24.1.1 问题 915 24.1.2 解决方案 915 24.1.3 工作原理 916 24.2 开始使用Spring Dynamic Modules 922 24.2.1 问题 922 24.2.2 解决方案 922 24.2.3 工作原理 922 24.3 用Spring Dynamic Modules输出服务 926 24.3.1 问题 926 24.3.2 解决方案 926 24.3.3 工作原理 926 24.4 在OSGi注册表中寻找一个具体服务 929 24.4.1 问题 929 24.4.2 解决方案 930 24.4.3 工作原理 930 24.5 发布多个接口的一个服务 932 24.5.1 问题 932 24.5.2 解决方案 932 24.5.3 工作原理 932 24.6 定制Spring Dynamic Modules 933 24.6.1 问题 933 24.6.2 解决方案 933 24.6.3 工作原理 933 24.7 使用SpringSource dm Server 935 24.7.1 问题 935 24.7.2 解决方案 935 24.7.3 工作原理 935 24.8 SpringSource的各工具 937 24.8.1 问题 937 24.8.2 解决方案 937 24.8.3 工作原理 937 24.9 小结 938 文摘 版权页:
jwx是开源的java公众号开发MVC框架,基于spring配置文件和微信消息或事件注解,通过微信上下文处理一个或多个微信公众号服务请求。目的主要有两个,其一生封装微信请求xml消息为java实体对象,将返回对象转换为xml响应消息;其二是封装微信接口为java服务。微信公众号采用web服务作为消息与第三方平台发生交互,数据格式主要是xml和json,普通的web请求响应机制采用xml数据格式交互,微信接口服务采用json数据格式。jwx主要对这两个方面做了封装处理,另外借鉴springmvc的请求处理方式,以WeixinDispatcherServlet作为消息分发控制器,通过消息组装工厂生成请求消息或事件实体,根据消息或事件型,在消息策略处理工厂查找处理策略,获取相应的微信处理方法,Servlet获取到处理方法后,请求线程池获取线程调用微信方法,根据微信方法的返回值,生成请求的xml响应。本说明文档将分章节说明jwx框架的特征、快速入门、配置、扩展等各个方面。 一、特征 消息重排自动处理,提供消息重排缓存接口 明文/加密模式无感知切换 常用的微信接口服务封装 提供线程池执行微信方法,方法调用线程池大小可配置 长任务消息推送 通过微信上下文配置支持多个微信公众号处理 提供统一的异常处理机制 提供access_token自动更新机制 请求消息组装 灵活的响应消息型 二、快速入门 本章教材提供一个最简单的例子,用户在微信公众号发一条foo的文本请求消息,公众号响应一条bar的文本响应消息。 1、maven配置文件 通过maven生成一个webapp项目,例如项目名为weixin,在maven配置文件pom.xml中添加jwx依赖,jwx的1.1.1jar包已经提交到maven中心仓库,通过中心仓库搜索jwx关键字可以获取jar包依赖配置。 com.github.jweixin jwx 1.1.1 2、web.xml文件配置 web.xml是web应用的配置文件,jwx从spring配置文件中获取配置信息,所以必须配置spring上下文环境;另外,需要配置微信消息处理分发Servlet(WeixinDispatcherServlet),用于处理微信送过来的请求消息或事件。jwx对springmvc没有依赖关系,web mvc框架可以根据实际需要配置。 org.springframework.web.context.ContextLoaderListener weixin com.github.jweixin.jwx.servlet.WeixinDispatcherServlet 1 weixin /wx/* load-on-startup表示Servlet在web应用启动阶段加载,数字代表了启动次序,如果项目使用了springmvc框架,可以调整该数字为2,放到springmvc框架后面启动加载,但实际上Servlet的启动次序并没有太大的关系。 spring配置是jwx必须的,如果没有配置spring上下文,jwx在启动阶段会报错。 url-pattern模式匹配微信公众号平台服务器配置的URL配置,如果需要处理多个微信公众号,可以配置多个servlet-mapping或者使用路径通配符匹配多个url链接。 3、spring配置文件 spring配置文件applicationContext.xml里面需要配置WeixinConfigurer,这是jwx唯一必须配置项,如果没有配置,启动阶段会报错。 com.telecomjs.yc.controller component-scan配置了微信接口服务,里面包含常用的微信公众号接口服务,例如菜单管理、消息服务、二维码服务、用户管理、微信网页授权、素材管理等服务内容,在web应用控制器和微信控制器里面可以通过@Autowired注解来注入服务。本配置并不是必须项。 WeixinConfigurer是唯一需要配置的部分,packages属性必须配置,里面是微信控制器包路径列表,WeixinDispatcherServlet在启动阶段会扫描包路径及其下面的子包路径,如果拥有@Weixin注解,则该会被当作微信控制器加载到微信上下文。 除了packages属性是必须配置的,其他配置都有缺省值,包括消息缓存、微信方法线程池的大小、微信方法调用超时阀值等,这部分内容放在配置部分说明了。 4、编写微信控制器配置完上面的3个部分,所有的配置文件部分就结束了,是不是很简单呢。下面我们只需要写微信控制器就能让我们的微信公众号活起来了。微信控制器是用@Weixin注解的普通,与sprngmvc里面的controller很似,方法的执行也很似。我们在com.telecomjs.yc.controller包下建一个javaWeixinController,如下: package com.telecomjs.yc.controller; import com.github.jweixin.jwx.context.Weixin; import com.github.jweixin.jwx.message.annotation.TextMsg; @Weixin(value="/wx/coreServlet", appID="xxx", appSecret="xxx", encodingAESKey="xxx", token="xxx") public class WeixinController { @TextMsg("foo") public String foo(){ return "bar"; } } @Weixin需要配置value值,这个实际就是微信服务器配置里面URL最后的部分,当然不包含域名和web应用的上下文,切记,不能包含web应用上下文,其他4个部分配置内容也是公众号配置内容,我们只需要登录到公众号看下填进去就行了。如果没有配置encodingAESKey,那么是不能处理加密消息的,如果有log4j的配置文件,启动阶段会给出告警信息的。 同一个公众号可以配置多个@Weixin注解控制器,其中只需要一个有其他4项配置就可以了,如果多个控制器配置了其他4个配置项,如果相对应的配置项值不相同,启动阶段会报错。 不同微信公众号是通过@Weixin的value值区分的,该值同时是微信上下文的查找关键字。 foo方法上面有@TextMsg注解,是定义的微信方法,在Servlet启动时通过包扫描加载到微信上下文对象中。jwx针对微信消息或事件型设计了一组微信注解,基本涵盖了微信公众号定义的消息和事件型。 @TextMsg是文本消息注解,代表请求型的是文本消息,value值是发送的文本消息内容。处理文本适配模式,@TextMsg还支持正则表达式适配模式,这部分内容在使用参考部分说明。 本例中微信方法并没有设置参数,实际可以灵活设置参数,例如我们可以在方法中设置HttpServletRequest request,HttpServletResponse response,InMessage in, WeixinContext context等参数,这部分内容也放在使用参考部分说明。 本例中方法的返回型是String,代表响应的消息内容是文本消息,jwx提供了丰富的返回值型,这部分内容会在使用参考部分详细说明。 5、启动web应用 上面就是这个最简单例子的全部内容,让我们启动web应用,进入到我们的公众号,输入foo文本提交,看看返回的是不是bar这个内容了,如果是,恭喜你,你已经初步掌握了jwx的使用方法。下面更多的内容等着你呢! 三、配置说明 spring配置文件中唯一需要配置的bean是WeixinConfigurer,是可选配置,但里面封装了微信接口服务,建议一定要配置spring配置文件中。 1、微信接口服务 微信接口服务位于com.github.jweixin.jwx.weixin.service包中,在spring配置文件中通过扫描包载入服务,在web mvc框架和微信控制器中都可以通过@Autowired注解注入,与其他spring普通的服务主键使用方式一致,服务每个方法都有accessToken参数,这个参数指的是微信access_token,在微信控制器方法中,可以通过设置方法的WeixinContext context参数获取,在web mvc框架中,可以通过WeixinContextHelper的静态方法getAccessToken(String url)获取。 CustomMsgService 客服消息服务 MassMsgService 群发消息服务 MaterialService 永久素材管理 MediaService 临时素材管理 MenuService 菜单服务 QrcodeService 二维码服务 TagService 标签服务 TemplateService 模板管理及消息发送 WebAuthService 微信网页授权服务 UserService 微信用户服务 SystemService 获取地址列表及长链接转短链接等其他型服务 2、WeixinConfigurer配置 WeixinConfigurer是微信上下文全局配置,里面包含了处理微信扫描、微信消息重排处理、微信方法执行线程池大小、微信方法调用超时阀值等方面的配置,packages包扫描配置是唯一必须的配置部分,这个配置在快速入门部分已经描述,其他部分配置都有缺省配置,不是必须配置部分。 a、微信消息重排处理messageKeyCache配置 微信在处理消息推送时,如果没有获得响应,会隔5秒重试,最多重试3次。jwx在接到消息推送时,需要判断该消息是否已经接受过,如果接受过,则需要放弃处理。jwx设计了MessageKeyCache接口用于处理消息重排,里面需要实现唯一的方法public boolean hasMessageKey(String key);如果系统已经缓存了消息key值,返回true。jwx实现了一个默认的消息key值缓存ConcurrentHashMapMessageKeyCache。如果我们要设置缓存清理间隔,可以采用如下配置: <!-- 设置消息key缓存清理间隔,单位秒 --> com.telecomjs.yc.controller 另外我们可以实现自己的消息key缓存,只需要实现MessageKeyCache接口就可以了,比如我们可以采用redis作为消息key值缓存数据库。 b、微信方法线程池大小threadPoolSize设置 微信方法是由Servlet在获取请求消息或事件的策略后取得,Servlet取得微信方法后,在线程池中获取线程执行微信方法。缺省线程池的大小是10个,如果微信公众并发比较频繁,我们可以调整线程池的大小,以提高处理效率。 如果我们调整线程池大小为100,可以采用如下配置: <!-- 设置消息key缓存清理间隔,单位秒 --> com.telecomjs.yc.controller <!-- 设置微信方法执行线程池大小 --> c、微信方法调用超时阀值weixinMethodTimeoutThreshold设置 微信推送消息或事件如果超过5秒,微信会中断连接,有时候微信方法的执行会超过5秒钟,针对这种情况,jwx采用微信方法调用超时阀值机制,如果微信方法调用线程不能在超时阀值内处理完毕,Servlet会先行返回http响应,后续Servlet会等待方法执行完毕,然后通过客服消息返回响应,对用户来说并没有感知。缺省的微信方法调用超时阀值是3000毫秒,该值可以通过配置调整,如下我们将超时阀值改成4秒: <!-- 设置消息key缓存清理间隔,单位秒 --> com.telecomjs.yc.controller <!-- 设置微信方法执行线程池大小 --> <!-- 设置微信方法调用超时阀值,单位毫秒 --> 四、使用参考 本部分会全面讲解jwx的概念及使用方法。 1、主要概念 微信上下文:微信上下文(WexinContext)是jwx最重要的部分,jwx可以同时处理多个微信公众号,每个公众号在jwx框架中对应一个微信上下文,微信上下文持有一个微信公众号所有的配置信息及处理策略。url是微信公众号配置的服务器地址的最后部分(不包括域名和web应用上下文),是识别微信公众号的唯一标识,透过url我们可以通过微信上下文帮助(WeixinContextHelper)的静态方法获取到微信上下文及访问token,另外,在微信方法中我们也可以通过注入WeixinContext参数来获得微信上下文。微信上下文还包含了微信的access_token、appID、appSecret、encodingAESKey这些微信公众号的配置内容。微信上下文还保存微信方法与消息注解的策略对应关系,是微信消息能够得到处理的最重要的部分。微信上下文通过@Weixin注解来配置。 微信消息注解:jwx定义了14个消息或事件注解,涵盖了目前所有的微信消息和事件型,这些注解定义在包com.github.jweixin.jwx.message.annotation中,微信注解代表了消息或事件型,可以通过微信注解配置识别请求消息型,获取相应的微信处理方法。 微信方法:被微信消息注解包围的方法,通过微信方法,我们可以处理微信公众号请求消息,返回公众号的响应消息。 2、@Weixin注解 @Weixin是用来配置微信上下文的,该注解使用在微信控制器上。每个被@Weixin注解包围的会在web应用启动时被扫描,配置项会加载到微信上下文中,@Weixin注解的参数说明: value:代表微信上下文关键字,不能为空,在微信公众号基本配置中,处于URL配置的最后部分。例如微信公众号的URL(服务器地址)配置是:http://nalan_weixin.tunnel.qydev.com/weixin/wx/coreServlet,其中http://nalan_weixin.tunnel.qydev.com是主机栏,/weixin是web应用的上下文栏,那么value值应该是/wx/coreServlet,一个公众号可以有多个拥有@Weixin注解,如果多个注解的value相同,则会认为是同一个微信上下文,在jwx中,区分上下文的唯一标识就是@Weixin注解的value值配置。@Weixin注解还有其他4个配置项,都有缺省值,在一个微信控制器配置了其他4个值,那么相同value值得控制器只需要配置value项就可以了,如果value配置项相同,而其他4个配置项的同项配置不同,jwx在初始启动扫描阶段会给出报错提示。 token:代表微信公众号基本配置中的Token(令牌)项的值。 encodingAESKey:代表微信公众号基本配置中的EncodingAESKey(消息加解密密钥),该项如果没有配置,那么jwx不能处理加密的请求消息,在jwx初始启动阶段会给出告警提示。如果我们配置了消息加解密方式为安全模式,没有配置encodingAESKey项,则运行阶段会报错。另外如果在加密请求消息到达时报如下错误:java.security.InvalidKeyException:illegal Key Size,则说明当前运行的JDK没有用JCE无限制权限策略文件替换相应的安全jar包,**解决方案:在官方网站下载JCE无限制权限策略文件(请到官网下载对应的版本, 例如JDK7的下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt,如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件;如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件**。 appID:代表微信公众号基本配置中的AppID(应用ID)。 appSecret:代表微信公众号基本配置中的AppSecret(应用密钥)。 3、微信方法 在微信控制器中,被微信消息(事件)注解包围的方法,被称为微信方法,微信方法是MVC框架里面的C部分,它控制着对请求消息的处理逻辑,并且返回响应消息。微信注解主要用于适配请求消息(事件)的型及关键字内容,当适配成功后,由对应的微信方法执行处理逻辑,并且通过方法的返回值返回响应消息。微信方法的参数在请求消息到达时由Servlet注入,目前微信方法参数可以是HttpServletRequest request,HttpServletResponse response,InMessage in, WeixinContext context里面的任意次序和数量的组合,参数中InMessage可以是与注解对应的子,对于@ExceptionHandler注解,可以添加Throwable及其子作为方法参数,需要注意的是如果参数型与实际消息型或异常型不能匹配,则该参数会被置为空。 4、微信注解 jwx定义了14个消息或事件注解,涵盖了目前所有的微信消息和事件型,下面逐个讲解没有注解的使用。 @TextMsg @ClickEvent 5、响应
要在Spring Security中实现第三方登录,可以使用Gitee作为示例。下面是实现的步骤: 1. 在Gitee上创建应用并获取相应的客户端ID和客户端秘钥。 2. 在Spring Boot项目中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> ``` 3. 在`application.yml`或`application.properties`文件中配置Gitee的相关信息: ```yaml spring: security: oauth2: client: registration: gitee: clientId: <your_client_id> clientSecret: <your_client_secret> redirectUriTemplate: "{baseUrl}/login/oauth2/code/{registrationId}" clientName: Gitee provider: gitee: authorizationUri: https://gitee.com/oauth/authorize tokenUri: https://gitee.com/oauth/token userInfoUri: https://gitee.com/api/v5/user userNameAttribute: name ``` 4. 创建一个登录控制器处理授权回调和获取用户信息: ```java @Controller public class LoginController { @GetMapping("/login") public String login() { return "login"; } @GetMapping("/login/oauth2/code/gitee") public String loginPage(HttpServletRequest request) { return "redirect:/oauth2/authorization/gitee"; } @GetMapping("/loginSuccess") public String loginSuccess() { return "success"; } } ``` 5. 创建一个自定义用户信息服务: ```java @Service public class CustomOAuth2UserService extends DefaultOAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2User oAuth2User = super.loadUser(userRequest); // 获取用户信息 // 可以在这里将用户信息存储到数据库或进行其他操作 return oAuth2User; } } ``` 6. 在配置配置`CustomOAuth2UserService`: ```java @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CustomOAuth2UserService customOAuth2UserService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/login**") .permitAll() .anyRequest() .authenticated() .and() .oauth2Login() .userInfoEndpoint() .userService(customOAuth2UserService); } } ``` 7. 创建登录页面 (`login.html`) 和登录成功页面 (`success.html`)。 现在,你可以通过访问 `/login` 来启动第三方登录流程了。选择 Gitee 作为登录方式并进行授权后,用户将被重定向到 `/loginSuccess` 页面。 请注意,以上只是一个简单的示例。实际情况中,你可能需要根据你的需求进行更多的配置和适配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不易撞的网名

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值