约定大于配置--实战

约定优于配置是一个简单的概念。 系统,类库,框架应该假定合理的默认值,而非要求提供不必要的配置。 在大部分情况下,你会发现使用框架提供的默认值会让你的项目运行的更快。

零配置并不是完全没有配置,而是通过约定来减少配置, 减少 XML

约定代码结构或命名规范来减少配置数量

如果模型中有个名为Sale的类,那么数据库中对应的表就会默认命名为sale。只有在偏离这一约定时,例如将该表命名为"products_sold",才需写有关这个名字的配置。

比如 EJB3 持久化,将一个特殊的Bean持久化,你所需要做的只是将这个类标注为 @Entity 。 框架将会假定表名和列名是基于类名和属性名。 系统也提供了一些钩子,当有需要的时候你可以重写这些名字.

比如 maven 项目约定,在没有自定义的情况下,源代码假定是在 /workspace/content-zh/src/main/java,资源文件假定是在/workspace/content-zh/src/main/resources 。测试代码假定是在 /workspace/content-zh/src/test。项目假定会产生一个 JAR 文件。Maven假定你想要把编译好的字节码放到 /workspace/content-zh/target/classes 并且在/workspace/content-zh/target 创建一个可分发的 JAR 文件。Maven 对约定优于配置的应用不仅仅是简单的目录位置,Maven 的核心插件使用了一组通用的约定,以用来编译源代码,打包可分发的构件,生成 web 站点,还有许多其他的过程。 Maven 的力量来自它的"武断",它有一个定义好的生命周期和一组知道如何构建和装配软件的通用插件。如果你遵循这些约定,Maven 只需要几乎为零的工作——仅仅是将你的源代码放到正确的目录,Maven 将会帮你处理剩下的事情。

比如 Yeoman 创建项目,只需一行代码

yeoman init angular

就会创建整个详细结构包括渲染路由的骨架,单元测试等

比如 HTML5 Boilerplate,为App的默认模板以及文件路径规范,无论是网站或者富UI的App,都可以采用这个模板作为起步。HTML5 Boilerplate的模板核心部分不过30行,但是每一行都可谓千锤百炼,可以用最小的消耗解决一些前端的顽固问题: 

采用更简洁的配置方式来替代XML

比如:hibernate.properties的 c3p0 方式:

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect

比如:hibernate.properties 的 JNDI 方式:

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \ org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQL82Dialect

比如 Apache Shiro 的 ini 配置

[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz

[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5

Hibernate通过代码配置

Configuration cfg = new Configuration()
    .addClass(org.hibernate.auction.Item.class)
    .addClass(org.hibernate.auction.Bid.class)
    .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
    .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
    .setProperty("hibernate.order_updates", "true");

Gradle 替代 Maven

采用 Maven

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>4.3.6.Final</version>
</dependency>

采用 Gradle 只需一行

org.hibernate:hibernate-core:4.3.6.Final

通过注解约定其含义来减少配置数量

spring注解

Spring会自动搜索某些路径下的Java类,并将这些java类注册为Bean实例,这样就省去了将所有 bean 都在 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.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.waylau.rest"/>

</beans>

注意:如果配置了<context:component-scan/>那么<context:annotation-config/>标签就可以不用在 xml 中配置了,因为前者包含了后者。另外<context:component-scan/>还提供了两个子标签<context:include-filter><context:exclude-filter>用来控制扫描文件的颗粒度,例如

<beans>
    <context:component-scan base-package="com.waylau.rest">
    <context:include-filter type="regex" expression=".*Stub.*Repository"/>
    <context:exclude-filter type="annotation"expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

代码实现

public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.scan("com.waylau.rest");
    ctx.refresh();
    MyService myService = ctx.getBean(MyService.class);
}

Spring会合适的将显示指定路径下的类全部注册成Spring Bean。 Spring通过使用特殊的Annotation来标注Bean类。

  • @Component :标注一个普通的Spring Bean类。
  • @Controller : 标注一个控制器组件类。
  • @Service: 标注一个业务逻辑组件类。
  • @Repository : 标注一个DAO组件类。

Hibernate注解

表与实体映射

@Entity
@Table(name="TBL_FLIGHT",
       schema="AIR_COMMAND",
       uniqueConstraints=
           @UniqueConstraint(
               name="flight_number",
               columnNames={"comp_prefix", "flight_number"} ) )
public class Flight implements Serializable {
    @Column(name="comp_prefix")
    public String getCompagnyPrefix() { return companyPrefix; }

    @Column(name="flight_number")
    public String getNumber() { return number; }
}

甚至 SQL 也可以注解

@Entity
@Table(name="CHAOS")
@SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)")
@SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?")
@SQLDelete( sql="DELETE CHAOS WHERE id = ?")
@SQLDeleteAll( sql="DELETE CHAOS")
@Loader(namedQuery = "chaos")
@NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where xml:id= ?", resultClass = Chaos.class)
public class Chaos {
    @Id
    private Long id;
    private Long size;
    private String name;
    private String nickname;
    //...
}

Jersey 2.X 实现 REST 和 MVC

@POST
@Produces({"text/html”})
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Template(name = "/short-link”) @ErrorTemplate(name = "/error-form")
@Valid
public ShortenedLink createLink(@NotEmpty @FormParam("link") final String link) {
    // ...
}

Shiro 的注解

没有注解的情况

//get the current Subject
Subject currentUser =
    SecurityUtils.getSubject();

if (currentUser.hasRole(“administrator”)) {
   //do something in here that only a administrator‏
} else {
    //don’t  do ‏
}

用了注解,简洁很多

@RequiresRoles( “administrator” )
public void openAccount( Account acct ) {
    //do something in here that only a administrator
}

Struts 2.x 注解

package com.waylau.actions;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

@Results({
  @Result(name="failure", location="fail.jsp")
})
public class HelloWorld extends ActionSupport {
  @Action(value="/different/url",
    results={@Result(name="success", location="http://struts.apache.org", type="redirect")}
  )
  public String execute() {
    return SUCCESS;
  }

  @Action("/another/url")

  public String doSomething() {
    return SUCCESS;
  }
}

参考

时间: 2024-10-15 14:21:54

约定大于配置--实战的相关文章

“约定优于配置”与Magento改造尝试四之block、helper和model加载

暂定本章为这个系列最后一章,还是继续沿用模块的别名(alias)概念 <modules> <Mage_Wishlist> <version>1.6.0.0</version> <alias>wishlist</alias> </Mage_Wishlist> </modules> 看下Magento一般是怎么定义block.helper和model的别名的 <blocks> <wishlist&

“约定优于配置”与Magento改造尝试二之布局xml文件加载

上一章讲到语言包加载的改造,这一章准备对布局xml文件的配置下手.把布局xml文件加载的改造放第二章,是因为本章开始会引入一个我自己定义的概念,相比第一章对底层的改动更大. 这个新概念我称之为模块的别名,设置方式如下(修改模块的config.xml): <modules> <Mage_Wishlist> <version>1.6.0.0</version> <alias>wishlist</alias> </Mage_Wishl

“约定优于配置”与Magento改造尝试一之语言包加载

上一篇文章("约定优于配置"与Magento)讲到,Magento的模块结构运用了大量的xml内容来做配置,其中有一些其实是可以用约定来代替的.从本篇文章开始我会尝试对Magento从底层做一些改造,来让系统支持按照约定而不需要实际配置来加载一些东西. 第一步先挑简单的来,原始情况下,一个模块对语言包(csv)的加载是通过如下方式配置指定的 <translate> <modules> <Mage_Wishlist> <files> <

“约定优于配置”与Magento

约定优于配置(convention over configuration)[1],也称作按约定编程[2],是一种软件设计范式,旨在减少软件 开发人员需做决定的数量,获得简单的好处,而又不失灵活性. 本质是说,开发人员仅需规定应用中不符约定的部分.例如,如果模型中有个名为Sale的类,那么数据库中对应的表 就会默认命名为sales.只有在偏离这一约定时,例如将该表命名为"products_sold",才需写有关这个名字的配置. 如果您所用工具的约定与你的期待相符,便可省去配置:反之,你可

Struts2 ActionWildcard(通配符配置)约定优于配置

新建web project:struts2_0500_actionwildcard Build Path 项目图: src:                   StudentAction.java TeacherAction.java struts.xml WebRoot: index.jsp Student_add.jsp Student_delete.jsp Student_edit.jsp Student_find.jsp Teacher_add.jsp Teacher_delete.j

PHP-5.5.10+Apache httpd-2.4.9在Windows系统下配置实战

原文 PHP-5.5.10+Apache httpd-2.4.9在Windows系统下配置实战 环境配置:   程序准备: PHP windows版本下载地址: http://windows.php.net/downloads/releases/php-5.5.10-Win32-VC11-x64.zip (下载后文件名为php-5.5.10-Win32-VC11-x64.zip)  Apache httpd windows版本下载地址: http://www.apachelounge.com/d

重磅图文详解:OpenNebula安装和节点配置实战

OpenNebula 4.10入门之安装和节点配置 环境说明: 所有系统环境管理端和节点宿主机都采用CentOS 6.6 x86_64 服务器使用情况: 1. 控制节点和存储节点使用同一台服务器. 2. 计算节点分别使用两台服务器 系统约定: cloud.webxury.com 192.168.15.100 (计算节点) cloud1.webxury.com 192.168.15.101 (计算节点) storage.webxury.com 192.168.15.200 (存储和控制) 系统最小

Apache2+Resin2.x集群配置实战

Apache2+Resin2.x集群配置 测试环境: 所需软件:apache2.x , Resin2.x 所需计算机:2 台 机器 A: IP 192.168.1.119 1. 安装好 Apache2.x 2. 修改 apache httpd.conf 配置文件, Include conf/include/remote-resin.conf 3. 生成 remote-resin.conf 放在 apache 的 conf/include 目录下,没有就创建一个 4. remote-resin.c

Windows Server 2003安全配置实战

Windows server2003是目前最为成熟的网络服务器平台,安全性相对于Windows 2000有大大的提高,但是2003默认的安全配置不一定适合我们的需要,所以,我们要根据实际情况来对Win2003进行全面安全配置.说实话,安全配置是一项比较有难度的网络技术,权限配置的太严格,好多程序又运行不起,权限配置的太松,又很容易被黑客入侵,做为网络管理员,真的很头痛,因此,我结合这几年的网络安全管理经验,总结出以下一些方法来提高我们服务器的安全性. 第一招:正确划分文件系统格式,选择稳定的操作