随着Spring在项目中大量的运用,现在的小朋友面试,绝大多数,都写着熟悉,熟练SSH。Spring的掌握似乎是JAVA程序员的标配。
不过,到底Spring的作用,我们为什么要用Spring这种问题,问过去,能够回答的少之又少。
当然百度一下,标准答案还是有很多的,比如 有效地组织你的中间层,降低耦合度,提高重用巴拉巴拉巴拉…
举个例子说明下?
回答: 呃………..
下面说下我个人的理解,有点长,需要重温下JAVA教科书经典片段。面对对象的开发,一般的JAVA教科书都会用一个例子来解释类,方法,继承等等。
比如:
有个父类,简单三个属性,名字,颜色,速度
public class ObjCar { private String strCarName; private String strCarColor; public String strCarSpeed = "50km/n"; public ObjCar(String inCarName,String inCarColor){ this.strCarName = inCarName; this.strCarColor = inCarColor; this.strCarSpeed = "50km/s";} public String getStrCarName() { return strCarName; } public String getStrCarColor() { return strCarColor; } public String getStrSpeed() { return strCarSpeed; } }
一个接口,描述方法
public interface CarMove { void move(); }
然后是继承父类,实现接口的子类
public class Car1 extends ObjCar implements CarMove { public Car1(String inCarName, String inCarColor) { super(inCarName, inCarColor);} @Override public void move() { System.out.println(this.getStrCarName() + " is" + this.getStrCarColor() + ",and move at " + this.strCarSpeed ); } public void getSpeed() { System.out.println(this.getStrCarName() + " move at " + this.strCarSpeed ); } }
上面这个有个自己方法getSpeed,实现了接口Move的方法,下面这个定义了自己的方法getColor
public class Car2 extends ObjCar implements CarMove { public Car2(String inCarName, String inCarColor) { super(inCarName, inCarColor);} @Override public void move() { System.out.println(this.getStrCarName() + " is " + this.getStrCarColor() + ",and move at " + this.strCarSpeed );} public void getColor() { System.out.println(this.getStrCarName() + " is " + this.getStrCarColor() );} }
调用则是
public class App { public static void main(String[] args) { dowork();} public static void dowork() { Car1 car1 = new Car1("Car1", "Red"); Car2 car2 = new Car2("Car2", "blue"); car1.move(); car1.getSpeed(); car2.move(); car2.getColor();} }
到这里,基本上传统的JAVA教课书上就会告诉你,啥是继承,啥是重载,有啥好处之类的,巴拉巴拉一大堆。。。。
但是,现实中,项目一般不会这么愉快的让你一步到位。
小明问:这样搞定了之后,假设客户说,我Car2也要有个getSpeed方法,咋办
教科书回答:这个时候,两个子类都有的话,你可以加个接口,在两个类里分别实现好了
继续问:但是我两个方法基本上是一样的,为啥不能写一个,而是要两个
教科书回答:这样的话,你可以在父类里面实现,这样子类就直接继承了这个方法了啊(继承的优势 巴拉巴拉 有一大堆)
继续问:但是我要用子类里特有的属性,方法怎么办
教科书:…呃…. 分别写咯
继续问:但是逻辑基本是一样的啊
教科书:……
小明追问:那如果我还有别的对象,Person,Monkey之类的也想用这个方法怎么办呢
教科书回答:…….
小明追问:现在的项目数据库有140个表,准备创建140个对象,都想用一个方法。。。
教科书回答:…….出去!!!
对于上述问题的解决,就是Spring的优势,
把希望共通实现的方法单独写在Bean里(SSH架构里面叫DAO)
@Repository public class CarMove { public void move(String strCarName,String strColor,String strSpeed) { System.out.println(strCarName + " is " + strColor + ",and move at " + strSpeed ); } public void getColor(String strCarName,String strColor) { System.out.println(strCarName + " is " + strColor ); } public void getSpeed(String strCarName,String strCarSpeed) { System.out.println(strCarName + " move at " + strCarSpeed ); } }
然后在另外一个Bean里面也调用逻辑(也就是所谓的业务逻辑Service层)
@Service public class CarService{ @Autowired private CarMove moveDao; @Autowired private LogOutput logOutputDao; public void dowork() { ObjCar car1 = new ObjCar("Car1", "Red"); ObjCar car2 = new ObjCar("Car2", "blue"); //可以在执行期,灵活组装我们的方法,随便客户折腾,他喜欢getColor就调用getColor,喜欢Move就Move。 moveDao.move(car1.getStrCarName(),car1.getStrCarColor(),car1.strCarSpeed); moveDao.getColor(car1.getStrCarName(),car1.getStrCarColor()); moveDao.getSpeed(car1.getStrCarName(),car1.strCarSpeed); logOutputDao.Output2Console(car1.getStrCarName()); //追加引入的方式支持别的方法 logOutputDao.Output2DB(car1.getStrCarName()); //car2也是,对象Bean根本不用定义方法,直接拿过来用就行 moveDao.move(car2.getStrCarName(),car2.getStrCarColor(),car2.strCarSpeed); moveDao.getColor(car2.getStrCarName(),car2.getStrCarColor()); moveDao.getSpeed(car2.getStrCarName(),car2.strCarSpeed); logOutputDao.Output2File(car2.getStrCarName()); //对象和方法并不耦合,所以别的数据Bean要使用也是分分钟的事情 ObjPerson person1 = new ObjPerson("Person1", "6km/h"); moveDao.move(person1.getStrName(),"yellow", person1.getStrSpeed()); logOutputDao.Output2File(person1.getStrName()); } }
这样本来要改很多类的事情,我们通过Spring框架略微修改就能搞定了,这也是为啥只要是成熟的JAVA组件或多或少都支持Spring的原因。
组件负责干活,使用Spring框架,具体怎么用,完全在Service里面组合一下就行了,节省了很多重新构建代码的工作。
基本就是这样,我也权当整理资料备份一下。