代码分析

定义格子

 package com.ftl.tetris;
/**
* 定义格子
*/ import java.awt.image.BufferedImage; public class Cell { private int row;
private int col;
private BufferedImage image; /**
* 构造方法,传递参数
* @param row 定义行
* @param col 定义列
* @param image
*/
public Cell(int row, int col, BufferedImage image) {
super();
this.row = row;
this.col = col;
this.image = image;
} /**
* drop函数,控制下降
* @return
*/
public void drop(){
row++;
} /**
* 右移
*/
public void moveRight()
{
col++;
} /**
* 左移
*/
public void moveLeft(){
col--;
} public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
} public String toString(){
return row + "," + col;
} }

定义方块

 package com.ftl.tetris;

 import java.util.Arrays;
import java.util.Random; import javax.swing.plaf.nimbus.State; /**
* 4格方块,7种形态
*/ public abstract class Tetromino {
protected Cell[] cells = new Cell[4]; //四个格子,静态方法
protected State[] states; public State[] getStates() {
return states;
} public void setStates(State[] states) {
this.states = states;
} /*旋转状态序列号, states = index % states.length*/
protected int index = 10000; /**
* 内部类
*/ protected class State{ int row0,col0,row1,col2,row2,col1,row3,col3; public State(int row0, int col0, int row1, int col2, int row2,
int col1, int row3, int col3) {
this.row0 = row0;
this.col0 = col0;
this.row1 = row1;
this.col2 = col2;
this.row2 = row2;
this.col1 = col1;
this.row3 = row3;
this.col3 = col3;
}
} /**
* 向右旋转
*/
public void roateRight(){
//取得变化的下个数据状态
//取得当前轴的row,col
//旋转后的数据= (row,col) + states[n]
this.index++;
State s = states[index % states.length];
System.out.println("index++" + this.index + "\tstates长度:" + states.length + "\t取余数 " + (index % states.length));
Cell o = cells[0];
int row = o.getRow();
int col = o.getCol();
cells[1].setRow(row + s.row1);
cells[2].setRow(row + s.row2);
cells[3].setRow(row + s.row3);
cells[1].setCol(col + s.col1);
cells[2].setCol(col + s.col2);
cells[3].setCol(col + s.col3);
}
/**
* 左旋转
*/
public void roateLeft(){
//取得变化的下个数据状态
//取得当前轴的row,col
//旋转后的数据= (row,col) + states[n]
this.index--;
State s = states[index % states.length];
System.out.println("index--" + this.index + "\tstates长度:" + states.length + "\t取余数 " + (index % states.length));
Cell o = cells[0];
int row = o.getRow();
int col = o.getCol();
cells[1].setRow(row + s.row1);
cells[2].setRow(row + s.row2);
cells[3].setRow(row + s.row3);
cells[1].setCol(col + s.col1);
cells[2].setCol(col + s.col2);
cells[3].setCol(col + s.col3);
} /**
* 工厂方法,产生四个随机方块
*/
public static Tetromino getOne() {
Random random = new Random();
int type = random.nextInt(7);
switch (type) {
case 0:
return new T();
case 1:
return new I();
case 2:
return new S();
case 3:
return new J();
case 4:
return new L();
case 5:
return new Z();
case 6:
return new O();
}
return null;
} /**
* 方块落下一个格子
*/
public void softDorp() {
for (int i = 0; i < cells.length; i++) {
cells[i].drop();
}
} /**
* 方块落左移一个格子
*/
public void moveLeft() {
for (int i = 0; i < cells.length; i++) {
cells[i].moveLeft();
}
} /**
* 方块落右移一个格子
*/
public void moveRight() {
for (int i = 0; i < cells.length; i++) {
cells[i].moveRight();
}
} public Cell[] getCells() {
return cells;
} public void setCells(Cell[] cells) {
this.cells = cells;
} /**
* 打印每个格子的行列信息
*/
public String toString() {
return Arrays.toString(cells);
} } /**
* T格子
*
* @author Administrator
*
*/
class T extends Tetromino{
public T() {
cells[0] = new Cell(0, 4, Tetris.T );
cells[1] = new Cell(0, 3, Tetris.T);
cells[2] = new Cell(0, 5, Tetris.T);
cells[3] = new Cell(1, 4, Tetris.T);
states = new State[4];
states[0] = new State(0,0,0,-1,0,1,1,0);
states[1] = new State(0,0,-1,0,1,0,0,-1);
states[2] = new State(0,0,0,1,0,-1,-1,0);
states[3] = new State(0,0,1,0,-1,0,0,1);
}
} /**
* I格子
*
* @author Administrator
*
*/
class I extends Tetromino {
public I() {
cells[0] = new Cell(0, 4, Tetris.I);
cells[1] = new Cell(0, 3, Tetris.I);
cells[2] = new Cell(0, 5, Tetris.I);
cells[3] = new Cell(0, 6, Tetris.I);
states = new State[]{
new State(0,0,0,-1,0,1,0,2),
new State(0,0,-1,0,1,0,2,0),
};
}
} /**
* Z格子
*
* @author Administrator
*
*/
class Z extends Tetromino {
public Z() {
cells[0] = new Cell(1, 4, Tetris.Z);
cells[1] = new Cell(0, 3, Tetris.Z);
cells[2] = new Cell(0, 4, Tetris.Z);
cells[3] = new Cell(1, 5, Tetris.Z);
states = new State[]{
new State(0,0,-1,-1,-1,0,0,1),
new State(0,0,-1,1,0,1,1,0),
};
}
} /**
* L格子
*
* @author Administrator
*
*/
class L extends Tetromino {
public L() {
cells[0] = new Cell(0, 4, Tetris.L);
cells[1] = new Cell(0, 3, Tetris.L);
cells[2] = new Cell(0, 5, Tetris.L);
cells[3] = new Cell(1, 3, Tetris.L);
states = new State[]{
new State(0,0,0,1,0,-1,-1,1),
new State(0,0,1,0,-1,0,1,1),
new State(0,0,0,-1,0,1,1,-1),
new State(0,0,-1,0,1,0,-1,-1),
};
}
} /**
* S格子
*
* @author Administrator
*
*/
class S extends Tetromino {
public S() {
cells[0] = new Cell(1, 4, Tetris.S);
cells[1] = new Cell(1, 3, Tetris.S);
cells[2] = new Cell(0, 4, Tetris.S);
cells[3] = new Cell(0, 5, Tetris.S);
states = new State[]{new State(0,0,0,-1,-1,0,-1,1),new State(0,0,-1,0,0,1,1,1)};
}
} /**
* J格子
*
* @author Administrator
*
*/
class J extends Tetromino {
public J() {
cells[0] = new Cell(0, 4, Tetris.J);
cells[1] = new Cell(0, 3, Tetris.J);
cells[2] = new Cell(0, 5, Tetris.J);
cells[3] = new Cell(1, 5, Tetris.J);
states = new State[]{
new State(0,0,0,-1,0,1,1,1),
new State(0,0,-1,0,1,0,1,-1),
new State(0,0,0,1,0,-1,-1,-1),
new State(0,0,1,0,-1,0,-1,1),
};
}
} /**
* O格子
*
* @author Administrator
*
*/
class O extends Tetromino {
public O() {
cells[0] = new Cell(0, 4, Tetris.O);
cells[1] = new Cell(0, 5, Tetris.O);
cells[2] = new Cell(1, 4, Tetris.O);
cells[3] = new Cell(1, 5, Tetris.O);
}
}

游戏主程序

 package com.ftl.tetris;

 import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask; import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel; /**
* 俄罗斯方块
*
* @author FTL1012
*
*/
public class Tetris extends JPanel {
private int score; // 分数
private int lines; // 行数
private Cell[][] walls; // 定义背景
private Tetromino tetromino; // 正在下降的格子
private Tetromino nextOne; // 下一个下降的格子 public static final int ROWS = 20; // 背景墙的行数
public static final int COLS = 10; // 背景墙的列数
private static final int CELL_SIZE = 26; //间距
private static final int FONT_COLOR= 0x667799; //字体颜色
private static final int FONT_SIZE = 30; private Timer timer; //定时调度
private int speed;
private int level;
private int index; //游戏运行状态
private int state;
private static final int RUNNING = 0;
private static final int PAUSE = 1;
private static final int GAME_OVER = 2; /**
* 背景图片
*
* @param args
*/
private static BufferedImage background;
public static BufferedImage T;
public static BufferedImage S;
public static BufferedImage I;
public static BufferedImage L;
public static BufferedImage J;
public static BufferedImage O;
public static BufferedImage Z;
public static BufferedImage gameOver;
public static BufferedImage pause; /**
* 静态代码块加载图片
*/
static {
try {
background = ImageIO.read(Tetris.class.getResource("tetris.png"));
gameOver = ImageIO.read(Tetris.class.getResource("gameover.png"));
pause = ImageIO.read(Tetris.class.getResource("pause.png"));
T = ImageIO.read(Tetris.class.getResource("T.png"));
I = ImageIO.read(Tetris.class.getResource("I.png"));
L = ImageIO.read(Tetris.class.getResource("L.png"));
O = ImageIO.read(Tetris.class.getResource("O.png"));
S = ImageIO.read(Tetris.class.getResource("S.png"));
J = ImageIO.read(Tetris.class.getResource("J.png"));
Z = ImageIO.read(Tetris.class.getResource("Z.png"));
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
} /**
* 画背景,画墙,画正在下落的方块,画下一个方块
*/
@Override
public void paint(Graphics g) {
// TODO 自动生成的方法存根
g.drawImage(background, 0, 0, null);
g.translate(15, 15); // 坐标系平移15个像素 //打印背景
paintWall(g);
//打印下落的方块
paintTetromino(g);
//打印即将下落的方块
paintNextmino(g);
//绘制分数
paintScore(g);
//绘制游戏状态
paintState(g);
} /**
* 绘制游戏状态
*/
private void paintState(Graphics g) {
switch (state) {
case PAUSE:
g.drawImage(pause, -15, -15, null);
break;
case GAME_OVER:
g.drawImage(gameOver, -15, -15, null);
break;
}
} /**
* 绘制分数
* @param g
*/
private void paintScore(Graphics g) {
int x = 290;
int y = 160;
g.setColor(new Color(FONT_COLOR));
Font font = g.getFont();
font = new Font(font.getName(),font.getStyle(),FONT_SIZE);
g.setFont(font);
String str = null;
str = "SCORE:" + score;
g.drawString(str, x, y);
y += 56;
str = "LINES:" + lines;
g.drawString(str, x, y);
y += 56;
str = "LEVEL:" + level;
g.drawString(str, x, y);
} /**
* 启动Action方法,初始化数组Walls,
* @param args
*/
public void action()
{
walls = new Cell[ROWS][COLS];
walls[2][2] = new Cell(2,2,T); //将强的第二行第二列设置为T方块的一个格子(2,2)
tetromino = Tetromino.getOne(); //正在下落的方块
nextOne = Tetromino.getOne(); //下一个即将下落的方块 this.state = RUNNING;
//增加键盘监听控制
KeyAdapter l = new KeyAdapter() { @Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
// int key = e.getKeyCode();
// switch (key) {
// case KeyEvent.VK_DOWN:
// softDorpAction();
// break;
// case KeyEvent.VK_RIGHT:
// moveRightAction();
// break;
// case KeyEvent.VK_LEFT:
// moveLeftAction();
// break;
// case KeyEvent.VK_SPACE:
// hardDropAction();
// break;
// case KeyEvent.VK_UP:
// rotateRightAction();
// break;
// }
int key = e.getKeyCode();
switch (state) {
case GAME_OVER:
processGameOverKey(key);
break;
case PAUSE:
processPauseKey(key);
break;
case RUNNING:
processRunningKey(key);
break;
}
repaint();
}
};
//点击按钮的时候,按钮获得焦点,对应处理一些逻辑
this.requestFocus();
this.addKeyListener(l); //定时方法
this.timer = new Timer();
this.timer.schedule(new TimerTask() {
public void run() {
speed = 40 - (lines / 2);
speed = speed < 1 ? 1 : speed;
level = 41 - speed;
if(state == RUNNING && index % speed == 0){
softDorpAction();
}
index++;
repaint();
}
}, 10, 13);
} /**
* 运行按钮
* @param key
*/
private void processRunningKey(int key) {
switch (key) {
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_DOWN:
softDorpAction();
break;
case KeyEvent.VK_RIGHT:
moveRightAction();
break;
case KeyEvent.VK_LEFT:
moveLeftAction();
break;
case KeyEvent.VK_SPACE:
hardDropAction();
break;
case KeyEvent.VK_UP:
rotateRightAction();
break;
case KeyEvent.VK_P:
this.state = PAUSE;
break;
} } /**
* 停止按钮
* @param key
*/
private void processPauseKey(int key) {
switch (key) {
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_C:
index = 0;
this.state = RUNNING;
break;
} } /**
* 游戏结束,重新开始
* @param key
*/
private void processGameOverKey(int key) {
switch (key) {
case KeyEvent.VK_Q:
System.exit(0); //退出游戏
break;
case KeyEvent.VK_S:
this.lines = 0;
this.score = 0;
this.walls = new Cell[ROWS][COLS];
this.tetromino = Tetromino.getOne();
this.nextOne = Tetromino.getOne();
this.state = RUNNING;
// this.index = 0;
break;
}
} /**
* 绘制正在下落的方块
* @param args
*/
public void paintTetromino(Graphics g)
{
if(tetromino == null)
{
return; //结束方法
}
//将每个格子的row 和 col转换为x,y,然后贴图
Cell[] cells = tetromino.cells;
for(int i = 0; i < cells.length; i++)
{
//cell 为每一个盒子
Cell cell = cells[i];
int x = cell.getCol() * CELL_SIZE;
int y = cell.getRow() * CELL_SIZE;
g.drawImage(cell.getImage(), x-1, y-1, null);
}
} /**
* 画下一个即将下落的方块
*/
public void paintNextmino(Graphics g)
{
if(nextOne == null)
{
return; //结束方法
}
//将每个格子的row 和 col转换为x,y,然后贴图
Cell[] cells = nextOne.cells;
for(int i = 0; i < cells.length; i++)
{
//cell 为每一个盒子
Cell cell = cells[i];
int x = (cell.getCol() + 10)* CELL_SIZE;
int y = (cell.getRow() + 1) * CELL_SIZE;
g.drawImage(cell.getImage(), x-1, y-1, null);
}
} /**
* 画墙
*
* @param args
*/
private void paintWall(Graphics g) {
// TODO 自动生成的方法存根
for (int row = 0; row < walls.length; row++) {
// line表示墙上的每一行
Cell[] line = walls[row];
for (int col = 0; col < line.length; col++) {
// cell表示墙上的每一个格子
Cell cell = line[col];
int x = col * CELL_SIZE;
int y = row * CELL_SIZE;
//如果cell为空,则表示没有格子
if(cell == null){
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}
//如果不为空,表示有格子,显示各自,x-1,y-1为了不让重叠,为了美观
else
{
g.drawImage(cell.getImage(), x-1, y-1, null);
}
// g.drawString(row+"," + col,x,y+CELL_SIZE);
} }
} /**
* 判断是否出界
*/
private boolean outOfBounds(){
Cell[] cells = tetromino.cells;
for(int i = 0; i < cells.length; i++)
{
Cell cell = cells[i];
int col = cell.getCol();
if(col < 0 || col >= COLS )
{
return true;
}
}
return false;
} /**
* 判断是否重合
*/
private boolean coinclude() {
Cell[] cells = tetromino.cells;
for (int i = 0; i < cells.length; i++) {
Cell cell = cells[i];
int row = cell.getRow();
int col = cell.getCol();
if (row >= 0 && row < ROWS && col >= 0 && col <= COLS
&& walls[row][col] != null) {
return true; //重合
}
}
return false;
} /**
* 判断右边是否出界
* @param args
*/
public void moveRightAction(){
tetromino.moveRight();
if(this.outOfBounds() || this.coinclude())
{
tetromino.moveLeft();
}
} /**
* 判断左边是否出界
* @param args
*/
public void moveLeftAction(){
tetromino.moveLeft();
if(this.outOfBounds() || this.coinclude())
{
tetromino.moveRight();
}
} /**
* 判断游戏是否结束:
*
*/ private boolean isGameOver(){
//如果下一个放开没有出场位置,游戏结束
//就是: 下一个出场方块每个ge子都有对于的墙上如果有格子
Cell[] cells = nextOne.cells;
for(Cell cell:cells){
int row = cell.getRow();
int col = cell.getCol();
if(walls[row][col] != null){
return true;
}
}
return false;
} /**
* 选择控制--右边
*/
private void rotateRightAction() {
tetromino.roateRight();
if(this.outOfBounds() || this.coinclude()){
tetromino.roateLeft();
} } private static int[] scoreTable = {0,1,10,50,100}; /**
*销毁行
*/
public void destoryLines()
{
int lines = 0;
//循环墙上的每一行,如果每一行都有格子,表示行满
for(int row = 0; row < walls.length; row++){
if(this.fullCells(row)){
deleteRow(row);
lines++;
}
}
this.score += scoreTable[lines];
this.lines += lines;
} /**
* 删除某行
*
*/
public void deleteRow(int row) {
for(int i = row; i >=1; i--)
{
System.arraycopy(walls[i-1], 0, walls[i], 0, COLS);
}
Arrays.fill(walls[0], null);
} /**
* 判断行是否满了
*/
public boolean fullCells(int row){
Cell[] line = walls[row];//获取每一个格子的行
for(Cell cell:line)
{
if(cell == null)
{
return false; //未满
}
}
return true;
} /**
* 格子落地
*/
public void landIntoWall(){
//获取正在下落的四个格子
Cell[] cells = tetromino.cells;
for(int i = 0; i< cells.length; i++)
{
Cell cell = cells[i];
int row = cell.getRow();
int col = cell.getCol();
//格子放在相应的位置
walls[row][col] = cell;
}
} /**
* 判断是否可以继续下落
* @param args
*/ private boolean canDrop(){
Cell[] cells = tetromino.cells;
//到达最后一行
for (int i = 0; i < cells.length; i++) {
Cell cell = cells[i];
int row = cell.getRow();
if( row == ROWS - 1)
{
return false; //不能下落
}
}
//下一行有格子
for(Cell cell:cells )
{
int row = cell.getRow() + 1;
int col = cell.getCol();
if( row >= 0 && row < ROWS && col >=0 && col <=COLS
&& walls[row][col] != null)
{
return false;
}
}
return true;
} /**
*下落流控制
*/
public void softDorpAction() {
if(this.canDrop()){
tetromino.softDorp();
}else{
this.landIntoWall();
this.destoryLines();
this.tetromino = this.nextOne;
this.nextOne = Tetromino.getOne();
}
} public void hardDropAction()
{
while(this.canDrop()){
this.softDorpAction();
}
landIntoWall();
destoryLines();
tetromino = nextOne;
nextOne = Tetromino.getOne();
} public static void main(String[] args) {
JFrame jf = new JFrame();
Tetris tetris = new Tetris();
tetris.setBackground(new Color(0x0000ff));
jf.add(tetris);
jf.setSize(530, 580);
jf.setLocationRelativeTo(null);
jf.setTitle("Go Fighting——FTL");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true); tetris.action();
} }

游戏截图

源码下载

附:程序略有小bug,感兴趣的朋友可以改改

点击下载

Java实例---俄罗斯方块的更多相关文章

  1. Java项目--俄罗斯方块

    Java项目--俄罗斯方块 百度盘链接 链接:http://pan.baidu.com/s/1mhQ9SYc 密码:9ujo 一.心得 二.游戏实例 游戏截图 目录结构 三.代码 1.主界面 Tetr ...

  2. Thrift入门及Java实例演示<转载备用>

    Thrift入门及Java实例演示 作者: Michael 日期: 年 月 日 •概述 •下载配置 •基本概念 .数据类型 .服务端编码基本步骤 .客户端编码基本步骤 .数据传输协议 •实例演示(ja ...

  3. Protocol Buffer技术详解(Java实例)

    Protocol Buffer技术详解(Java实例) 该篇Blog和上一篇(C++实例)基本相同,只是面向于我们团队中的Java工程师,毕竟我们项目的前端部分是基于Android开发的,而且我们研发 ...

  4. JAVA实例

     JAVA实例1  1 package Demo3; import java.io.File; import java.io.FileReader; import java.io.IOExceptio ...

  5. Java 实例 - 如何执行指定class文件目录(classpath) Java 实例 J

    Java 实例 - 如何执行指定class文件目录(classpath)  Java 实例 如果我们 Java 编译后的class文件不在当前目录,我们可以使用 -classpath 来指定class ...

  6. Java-Runoob-高级教程-实例-方法:15. Java 实例 – 重载(overloading)方法中使用 Varargs

    ylbtech-Java-Runoob-高级教程-实例-方法:15. Java 实例 – 重载(overloading)方法中使用 Varargs 1.返回顶部 1. Java 实例 - 重载(ove ...

  7. Java-Runoob-高级教程-实例-方法:14. Java 实例 – Varargs 可变参数使用

    ylbtech-Java-Runoob-高级教程-实例-方法:14. Java 实例 – Varargs 可变参数使用 1.返回顶部 1. Java 实例 - Varargs 可变参数使用  Java ...

  8. Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用

    ylbtech-Java-Runoob-高级教程-实例-方法:13. Java 实例 – for 和 foreach循环使用 1.返回顶部 1. Java 实例 - for 和 foreach循环使用 ...

  9. Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用-um

    ylbtech-Java-Runoob-高级教程-实例-方法:12. Java 实例 – Enum(枚举)构造函数及方法的使用 1.返回顶部 1. Java 实例 - Enum(枚举)构造函数及方法的 ...

随机推荐

  1. Check类之TypeValidation

    (1)Validator类的visitTypeApply()方法 实例1: class TestTypeVal<T extends InputStream>{ TestTypeVal< ...

  2. Ubuntu 16.04 RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller” 不能上网

    来源:http://forum.ubuntu.org.cn/viewtopic.php?f=116&t=463646 1.执行如下命令 uname -a sudo lspci -knn sud ...

  3. JavaScript数据结构-6.优先队列

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. java代理-cglib

    前面说到了java的动态代理,但是动态代理依赖于接口,这次来看看cglib来实现的代理... 假设有如下方法,这回没有说接口哦~ package proxy.cglibProxy; public cl ...

  5. Linux下批量修改文件及文件夹所有者及权限

    Linux下批量修改文件及文件夹所有者及权限需要使用到两个命令,chmod以及chown 例:对/opt/Oracle/目录下的所有文件与子目录执行相同的权限变更: chmod -R 700 /opt ...

  6. 【LeetCode题解】2_两数相加

    目录 [LeetCode题解]2_两数相加 描述 方法一:小学数学 思路 Java 代码(非递归写法) Java 代码(递归写法) Python 代码(非递归写法) [LeetCode题解]2_两数相 ...

  7. Java泛型的逆变

    在上篇<Java泛型的协变>这篇文章中遗留以下问题——协变不能解决将子类型添加到父类型的泛型列表中.本篇将用逆变来解决这个问题. 实验准备 我们首先增加以下方法,见代码清单1所示. 代码清 ...

  8. request发送json-rpc请求

    直接贴代码吧: let url = '/rest/2.0/res/auth_token?session=' + session url += getUrlTokenQuery() const meth ...

  9. MVC中学到的小知识(MVC中的跳转,传参)

    1.mvc中视图中的href="XXX",这个XXX是控制器地址,不是另一个视图.(这里的href语句只能转向控制器,不能直接转向视图),如果要实现转向视图,可以先转到控制器,然后 ...

  10. 【原】Spring和Dubbo基于XML配置整合过程

    背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构 当网站流量很小时,只需一个 ...