Expert One-on-One J2EE Development without EJB
Rod Johnson

Spring 模块

Overview of the Spring Framework

依赖注入还是控制反转?

依赖注入(Dependency Injection)
控制反转(Inversion of Control)
“The question is, what aspect of control are [they] inverting?” Martin Fowler posed this question about Inversion of Control (IoC) on his site in 2004. Fowler suggested renaming the principle to make it more self-explanatory and came up with Dependency Injection.

核心容器

  • spring-core
  • spring-beans
  • spring-context
  • spring-context-support
  • spring-expression

AOP模块

  • spring-aop
  • spring-aspects

数据访问

  • spring-jdbc
  • spring-tx
  • spring-orm
  • spring-oxm
  • spring-jms

Web

  • spring-web
  • spring-webmvc
  • spring-websocket
  • spring-webmvc-portlet

消息

  • spring-messaging

测试

  • spring-test

场景

Spring全栈

Typical full-fledged Spring web application

集成三方Web框架

Spring middle-tier using a third-party web framework

远程调用

Remoting usage scenario


Node包管理器

一个自动任务运行器

安装Grunt

npm install -g grunt-cli
npm install grunt

NPM简单命令

npm search <word>
npm list
npm install -g <package>
npm install <package>
npm update -g
npm update
npm update <package>
npm uninstall <package>

安装

npm --registry https://registry.npm.taobao.org install <package>
npm config set registry https://registry.npm.taobao.org
npm init
npm install grunt --save-dev
npm install \
grunt-contrib-clean\
grunt-contrib-jshint \
grunt-contrib-concat \
grunt-contrib-uglify \
grunt-contrib-copy \
grunt-contrib-watch \
grunt-contrib-qunit \
grunt-contrib-cssmin \
--save-dev
//.npmrc
# proxy=http://127.0.0.1:8087/
# https-proxy=http://127.0.0.1:8087/
registry=https://registry.npm.taobao.org

一键安装

npm install
//package.json
{
  "name": "hello",
  "version": "0.1.1",
  "description": "Hello Grunt",
  "main": "index.js",
  "scripts": {
    "test": "grunt qunit"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/Halo9Pan/boke.git"
  },
  "keywords": [
    "grunt",
    "example"
  ],
  "author": "Halo9Pan <halo9pan@gmail.com>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/Halo9Pan/boke/issues"
  },
  "homepage": "https://github.com/Halo9Pan/boke#readme",
  "devDependencies": {
    "grunt": "^0.4.5",
    "grunt-contrib-clean": "^0.6.0",
    "grunt-contrib-concat": "^0.5.1",
    "grunt-contrib-copy": "^0.8.1",
    "grunt-contrib-cssmin": "^0.14.0",
    "grunt-contrib-jshint": "^0.11.3",
    "grunt-contrib-qunit": "^0.7.0",
    "grunt-contrib-uglify": "^0.9.2",
    "grunt-contrib-watch": "^0.6.1"
  }
}

命令脚本文件Gruntfile.js

module.exports = function(grunt) {

  // 配置Grunt各种模块的参数
  grunt.initConfig({
    clean: [
      'dist'
    ],
    jshint: {},
    concat: {
      options: {
        separator: ';',
        sourceMap: true
      },
      dist: {
        src: [
          'public/components/jquery/dist/jquery.js',
          'public/components/underscore/underscore.js',
          'public/components/backbone/backbone.js'
        ],
        dest: 'dist/components.min.js'
      },
      min: {
        src: [
          'public/components/jquery/dist/jquery.min.js',
          'public/components/underscore/underscore-min.js',
          'public/components/backbone/backbone-min.js'
        ],
        dest: 'dist/components.min.js'
      }
    },
    uglify: {
      options: {
        mangle: true,
        beautify: true
      },
      target: {
        expand: true,
        cwd: 'boilerplate/js/',
        src: ['*.js', '!*.min.js'],
        dest: 'dist/js/',
        ext: '.min.js'
      }
    },
    cssmin: {
      minify: {
        expand: true,
        cwd: 'boilerplate/css/',
        src: ['*.css', '!*.min.css'],
        dest: 'dist/css/',
        ext: '.min.css'
      },
      combine: {
        files: {
          'dist/css/public.min.css': [
            'public/components/bootstrap/dist/css/bootstrap.min.css',
            'public/components/bootstrap/dist/css/bootstrap-theme.min.css'
          ]
        }
      }
    },
    watch:  { /* watch的参数 */ }
  });

  // 从node_modules目录加载模块文件
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-qunit');

  // 每行registerTask定义一个任务
  grunt.registerTask('default', ['concat', 'uglify']);
  grunt.registerTask('check', ['jshint']);
  grunt.registerTask('css', ['cssmin:minify','cssmin:combine']);

};

前端包管理器

一个可以帮助你管理你的应用的前端依赖库的包管理器

安装Bower

npm install -g bower
bower -v

寻找包

bower search <word>

安装包

bower install <package>
bower install <package>#<version>
//.bowerrc
{
  "directory" : "public/components"
  "proxy": "http://127.0.0.1:8087",
  "https-proxy": "http://127.0.0.1:8087"
}

一键安装

bower install
//bower.json
{
  "name": "hello",
  "version": "0.1.1",
  "homepage": "http://blog.halo9pan.cn",
  "authors": [
    "Halo9Pan <halo9pan@gmail.com>"
  ],
  "description": "Hello Bower!",
  "main": "main.js",
  "moduleType": [
    "amd",
    "es6"
  ],
  "keywords": [
    "bower",
    "example"
  ],
  "license": "MIT",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "public/components",
    "test",
  ],
  "dependencies": {
    "jquery": "~2.1.4",
    "bootstrap": "~3.3.5",
    "backbone": "~1.2.3",
    "jquery-ui": "~1.11.4"
  }
}

列出安装的包

bower list

更新包

bower update
bower update <package>

卸载包

bower uninstall <package>

Apache Maven
Maven Users Centre
MVN Repository
Maven Central Repository
Available Plugins

常用命令

  • mvn –version
  • export MAVEN_OPTS=”-Xmx1024m -XX:MaxPermSize=128m”
  • set MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128m
  • mvn help:system 环境变量和系统属性
  • mvn help:effective-pom 查看有效POM文件
  • mvn dependency:tree 查看依赖树
  • mvn dependency:build-classpath 查看依赖CLASSPATH
  • mvn dependency:resolve 下载依赖包
  • mvn dependency:sources 下载依赖包源代码

Project Object Model

<project>
  <parent>...</parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>...</groupId>
  <artifactId>...</artifactId>
  <version>...</version>
  <packaging>...</packaging>
  <name>...</name>
  <description>...</description>
  <url>...</url>
  <inceptionYear>...</inceptionYear>
  <licenses>...</licenses>
  <organization>...</organization>
  <developers>...</developers>
  <contributors>...</contributors>
  <dependencies>...</dependencies>
  <dependencyManagement>...</dependencyManagement>
  <modules>...</modules>
  <properties>...</properties>
  <build>...</build>
  <reporting>...</reporting>
  <issueManagement>...</issueManagement>
  <ciManagement>...</ciManagement>
  <mailingLists>...</mailingLists>
  <scm>...</scm>
  <prerequisites>...</prerequisites>
  <repositories>...</repositories>
  <pluginRepositories>...</pluginRepositories>
  <distributionManagement>...</distributionManagement>
  <profiles>...</profiles>
</project>

Super POM

MAVEN_HOME/lib/maven-model-builder-3.X.X.jar - org/apache/maven/model/pom-4.0.0.xml

代理设置

<proxy>
  <id>internal_proxy</id>
  <active>true</active>
  <protocol>http</protocol>
  <username>proxyuser</username>
  <password>proxypass</password>
  <host>127.0.0.1</host>
  <port>8087</port>
  <nonProxyHosts>repo.halo9pan.cn|repo.hinkstack.info</nonProxyHosts>
</proxy>

服务器认证

<server>
  <id>central</id>
  <username>your_username</username>
  <password>your_password</password>
</server>

Password Encryption

Maven + SVN

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>cn.halo9pan</groupId>
  <artifactId>hello-maven</artifactId>
  <version>1.0.0</version>
  <scm>
    <connection>scm:svn:http://localhost/svn/nc</connection>
    <developerConnection>scm:svn:https://localhost/svn/nc</developerConnection>
    <url>
    https://localhost/svn/nc
    </url>
  </scm>
  <build>
    <plugins>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-scm-plugin</artifactId>
      <version>1.9</version>
      <configuration>
        <connectionType>
        connection
        </connectionType>
      </configuration>
      </plugin>
    </plugins>
  </build>
</project>
  • scm:add
  • scm:bootstrap
  • scm:branch
  • scm:checkin
  • scm:checkout
  • scm:diff
  • scm:edit
  • scm:list
  • scm:remove
  • scm:status
  • scm:tag
  • scm:update

本地库

USER_HOME/.m2/repository MAVEN_HOME/conf/settings: /path/to/local/repo

镜像

<mirror>
  <id>Central</id>
  <url>http://repo1.maven.org/maven2</url>
  <mirrorOf>central</mirrorOf>
</mirror>
<mirror>
  <id>internal.mirror.halo9pan.cn</id>
  <url>http://internal.mirror.halo9pan.cn/maven/</url>
  <mirrorOf>*</mirrorOf>
</mirror>

发布

<distributionManagement>
  <repository>
  <id>local-file-repository</id>
  <name>Local File Repository</name>
  <url>file:///home/halo9pan/maven/deploy</url>
  </repository>
</distributionManagement>

生命周期

MAVEN_HOME/lib/maven-core-3.2.3.jar - META-INF/plex/components.xml
mvn help:describe -Dcmd=deploy

Clean

pre-clean -> clean -> post-clean

Default

validate -> initialize -> generate-sources -> process-sources -> generate-resources -> process-resources -> compile -> process-classes -> generate-test-sources -> process-test-sources -> generate-test-resources -> process-test-resources -> test-compile -> process-test-classes -> test -> prepare-package -> package -> pre-integration-test -> integration-test -> post-integration-test -> verify -> install -> deploy

Site

pre-site -> site -> post-site -> site-deploy

阶段、目标

Packaging
process-resources – resources:resources
compile – compiler:compile
process-test-resources – resources:testResources
test-compile – compiler:testCompile
test – surefire:test
package – jar:jar
install – install:install
deploy – deploy:deploy

最佳实践

依赖管理 dependencyManagement

定义 parent module

使用 properties

不要重复 parent module 的 groupId 和 version

仔细遵循命名规范

使用 profiles

重用已有的插件

release 插件

enforcer 插件

不要同时使用 release 和 snapshot 版本的库

尽可能少的库

使用镜像而不是修改库 URL

保留默认目录结构

开发时使用 SNAPSHOT 版本

去除无用的依赖

使用 archetypes 新建项目

DIY 避免重复工作


MyChrome

墙内升级 Chrome 的利器:MyChrome,选择sina.com.cn的源就可以在墙内升级了

命令行启动参数

没有官方的启动参数文档,只有一个三方的文档,是作者根据 Chrome 分析出来的:List of Chromium Command Line Switches 介绍一些常用的:

  • –user-data-dir 指定用户数据目录,每个 Chrome 使用独立的数据目录,比如普通上网浏览用一个,开发时用一个,每个数据目录有不同的配置、扩展和应用。这是比 Profile 更高一级的隔离。同一数据目录下的 Profile 虽然也能配置不同的设置、扩展和应用,但是所有的 Profile 的扩展会都启动,消耗内存。
  • –incognito 直接用隐身模式启动。
  • –show-app-list 打开 Chrome 应用列表。
  • –disable-plugins-discovery 禁用所有的插件,世界清静了。
  • –disable-extensions 禁用所有的扩展,世界空白了,只剩下 Chrome 了。
  • –remote-debugging-port 远程调试端口
  • –enable-devtools-experiments –enable-experimental-canvas-features –enable-experimental-web-platform-features –enable-experimental-websocket –enable-encrypted-media –enable-accelerated-2d-canvas –enable-webgl-draft-extensions 打开各种实验功能,体验新特性时使用,但是通过命令行设置不一定有效 -_-!

chrome://

  • chrome://version/ 查看版本、执行文件路径以及数据文件路径
  • chrome://flags/ 可以修改一些 Chrome 的细节配置,不过这些配置开关大部分都是实验性的
  • chrome://dns/ 可以查看 Chrome DNS 的预解析,修改 host 文件无效时可以看看这里
  • chrome://memory/ 查看当前 Chrome 的内存消耗,比 Shift+Esc 更详细
  • chrome://net-internals/ Chrome 和网络相关的详细信息,事件捕获、预加载、代理、DNS、Sockets、HTTP2等
  • chrome://quota-internals/ Chrome 磁盘存储的配额信息
  • chrome://sync-internals/ Chrome 账户同步信息
  • chrome://profiler/ Chrome 性能调优信息,每一步执行的详细步骤以及消耗等
  • chrome://user-actions/ 捕获用户的所有操作
  • chrome://settings/ 设置
  • chrome://extensions/ 扩展
  • chrome://downloads/ 下载
  • chrome://history/ 历史
  • chrome://bookmarks/ 书签
  • chrome://about/ 常用的都在这里了(^-^)V

DevTools

Ctrl+Shift+I 欢迎来到 Chrome DevTools,神奇强大的工具

DevTools 目前(45.0.2454.85)主要包括以下八个主要功能组: Ctrl+[ Ctrl+]

Elements

DOM元素和样式

Resources

Network

Sources

Timeline

Profiles

Audits

Console

console.log("The current time is:", Date.now())
console.debug("The current time is:", Date.now())
console.info("The current time is:", Date.now())
console.error("The current time is:", Date.now())
console.warn("The current time is:", Date.now())
console.group("Console group");
console.log("The current time is:", Date.now());
console.groupEnd();
console.table([[1,2,3], [2,3,4]]);
console.log("The current time is: %O", Date())
console.log("%c天空深蓝", "color: DeepSkyBlue; font-size: large");
console.log(document)
console.dir(document)
console.clear()
console.time("Array initialize");
    var a = new Array(100000);
    console.assert(a.length > 200000, "a is > 2000000");
    for (var i = a.length - 1; i >= 0; i--) {
        if(i % 100 == 0) {
            console.timeStamp("100 Objects created.");
        }
        a[i] = new Object();
    };
console.timeEnd("Array initialize");
monitorEvents(document.body, "click");
unmonitorEvents(document.body);
debugger;
$()
$$()
$x()
$0 - $4
profile()
profileEnd()

小技巧

  • Ctrl + P 快速打开文件
  • Ctrl + Shift + F 在源代码中搜索
  • Ctrl + G 跳转到指定行数
  • $ 在控制台查找元素
  • Ctrl 多选
  • Preserve log 保存日志
  • {} 格式化代码
  • 仿真设备
  • Emulation–>Sensors 设备仿真传感器
  • 颜色选择器
  • 强制元素状态
  • 动画控制
  • Ctrl + D 多匹配
  • Shift + Click 颜色格式转换
  • Workspaces 神奇的本地开发环境

我的 Chrome 开发扩展和应用