文章目录
-
- 1.Spring的两个核心分类
- 2.何为IOC(控制反转)?
- 3.为什么需要IOC??
-
-
-
- 第一步:先写Dao层的接口和实现类
- 第二步:写Service层(应用层)
- 第三步:写一个测试类,测试一下
- 出现了问题:程序的耦合性太强
-
- 1.使用setter方法改进
- 2.使用构建函数改进
-
-
1.Spring的两个核心分类
需要学习IOC容器,因为以后可以用其来整合MyBatis,Hebernate,Stuts2等框架
需要学习AOP(面向切面编程)因为可以用于声明式事务
2.何为IOC(控制反转)?
控制:资源的获取
1.主动式:需要什么资源自给创建即可
BookServlet{
BookService service = new BookService();
AirPlan airPlan = new AirPlan();
.....
}
总之,所谓的主动式就是:你需要什么对象你就自给去创建什么对象,但是这种方式会出现一定的问题,一会儿我们来看一个例子说明他的问题所在。
2.被动式:资源的获取不再是自己创建,而是交给一个容器来创建和设置
BookServlet{
BookService service ;
public void test1(){
service.checkout();
}
}
3.容器:管理所有的组件(有功能的类)
假设BookServlet和BookService都受容器管理,哪些容器就可以自动的探查出哪些组件需要另一些组件,容器就会帮我们创建对象,然后把对象赋值过去;
即主动的获取资源变为被动的接受;
4.DI(依赖注入)
容器能够知道哪个类运行的时候,需要另一个类;容器通过反射机制将容器中准备好的BookService对象注入给BookServlet中
3.为什么需要IOC??
下面通过一个例子来看一下传统的自己new对象的方式到底存在什么样的问题??
第一步:先写Dao层的接口和实现类
首先,我们先在Dao层中写一个接口,这个接口有三个实现类
UserDao接口:
public interface UserDao {
void getUser();
}
UserDaoSqlServerImpl实现类:
public class UserDaoMySqlImpl implements UserDao {
public void getUser() {
System.out.println("MySql数据库");
}
}
UserDaoMysqlImpl实现类:
public class UserDaoMySqlImpl implements UserDao {
public void getUser() {
System.out.println("MySql数据库");
}
}
UserDaoOracleImpl实现类:
public class UserDaoOracleImpl implements UserDao {
public void getUser() {
System.out.println("Oracle数据库");
}
}
第二步:写Service层(应用层)
在应用层中,我们去调用dao层中UserDao接口中的抽象方法。
先写一个Userservice接口:
public interface UserService {
void getUser();
}
写一个UserService接口的实现类:
//想要在业务层中调用dao层中的方法
public class UserServiceImpl implements UserService {
//调用dao层中的方法,就要首先new实现类的对象
//1.我想使用mysql数据库
private UserDao userDao = new UserDaoMySqlImpl();
public void getUser() {
userDao.getUser();
}
}
第三步:写一个测试类,测试一下
我们在测试类中创建Service层中的接口的对象,然后调用Service层中的方法
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.getUser();
}
}
出现了问题:程序的耦合性太强
完成上面的程序以后,我们思考一个问题:我在UserServiceImpl类中调用了UserDaoMySqlImpl实现类,那么如果我想调用UserDaoOracleImpl实现类呢?
又或者想调用UserDaoSqlSever实现类呢?
那么就会出现下面的问题:
//想要在业务层中调用dao层中的方法
public class UserServiceImpl implements UserService {
//调用dao层中的方法,就要首先new实现类的对象
//1.我想使用mysql数据库
//private UserDao userDao = new UserDaoMySqlImpl();
//2.我想使用Oracle数据库
//private UserDao userDao1 = new UserDaoOracleImpl();
//3.我想使用SqlServer数据库
private UserDao userDao2 = new UserDaoSqlServerImpl();
public void getUser() {
//userDao.getUser();
//userDao1.getUser();
userDao2.getUser();
}
}
我想使用换个类调用就会重新修改代码,代码的耦合性太强,这不是我们想要的结果。。
问题来了,如何进行改进?
有两种改进方法:
1.使用setter方法改进
下面我们再写一个UserService接口的实现类:UserServiceImpl2
在这个实现类中我们加入一个setter方法
public class UserServiceImpl2 implements UserService {
//使用多态机制
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
然后重新写一个测试类,看一下有哪些好处:
public class MyTest2 {
public static void main(String[] args) {
UserServiceImpl2 userService = new UserServiceImpl2();
//1.我想使用mysql数据库
userService.setUserDao(new UserDaoMySqlImpl());
userService.getUser();
//2.我想使用SqlServer数据库
userService.setUserDao(new UserDaoSqlServerImpl());
userService.getUser();
//3.我想使用Oracle数据库
userService.setUserDao(new UserDaoOracleImpl());
userService.getUser();
}
}
通过改进后可以发现,程序的耦合性降低了,不需要再修改service层中的代码,只需要在测试类中修改就好。
2.使用构建函数改进
本质上和setter方法形同,不再赘述
public class UserServiceImpl3 implements UserService {
//使用多态机制
private UserDao userDao;
public UserServiceImpl3(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
}
public class MyTest3 {
public static void main(String[] args) {
UserServiceImpl3 userService =
new UserServiceImpl3(new UserDaoMySqlImpl());
userService.getUser();
userService = new UserServiceImpl3(new UserDaoOracleImpl());
userService.getUser();
}
}