随着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里面组合一下就行了,节省了很多重新构建代码的工作。
基本就是这样,我也权当整理资料备份一下。