Spring是什么?为什么要使用Spring?

本文介绍了Spring框架作为JavaEE开发的轻量级解决方案,通过对比传统方式和Spring模式完成业务逻辑,强调其在解耦和简化代码中的优势,以及Spring如何通过工厂模式和配置文件实现对象管理。
摘要由CSDN通过智能技术生成

目录

前言

一、Spring是什么?

1.1 轻量级

1.2 JavaEE的解决方案

二、为什么要使用Spring

2.1 传统方式完成业务逻辑

2.2 使用Spring模式完成业务逻辑

三、为什么使用Spring?


前言

本文主要介绍Spring是什么,并且解释为何要去使用Spring,通过一个实际的案例来展示了Spring的强大之处。通过本章正式开始Spring的学习!


一、Spring是什么?

Spring是一个轻量级的Java企业开发的解决方案,整合了许多优秀的设计模式。

1.1 轻量级

  • 对于运行环境是没有要求的

        开源的可以,收费的也可以

  • 代码的移植性高

        不用实现额外的接口

1.2 JavaEE的解决方案

为什么说Spring是JavaEE中的解决方案呢,在项目开发的过程中类似于Mybatis这种框架只是针对于DAO这一层进行操作,但是Spring对每一个层次都有相对的解决方案,所以这里称Spring为JavaEE中的解决方案。

二、为什么要使用Spring

2.1 传统方式完成业务逻辑

上面只是简单的介绍了一下Spring,对于Spring详细介绍后面再来分析,接下来就分析一下为什么要使用Spring。

对于传统的创建对象的模式,我们是通过直接new对象的方式。假设我现在有一个User类,我要通过UserDao类进行业务操作,然后通过UserService对UserDao类进行控制操作。那么传统的方法就是一步一步的new对象。

1)首先,创建一个User类

public class User {
    private String id;
    private String name;
    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }
}

2)在UserDao中写出相应的业务操作

public class UserDao {
    public void login(User user) {
        // 这里本来是需要写crud的具体操作的,但是为了演示方便就不写了
        System.out.println("name:"+user.name+",password:"+user.password);
    }
}

3)在UserService中进行相应的操作

public class UserService {
    UserDao userDao = new UserDao();
    public void login(User user) {
        userDao.login(user);
    }
}

4)进行测试,模拟登录的过程

@org.junit.Test
public void test() {
    UserService userService = new UserService();
    User user = new User("张三","123456");
    userService.login(user);
}

此时该业务逻辑就完成了 

假设这个时候UserService过时了,我想重新写一个UserServiceNew来操作业务逻辑,对于传统的方式可能就需要对代码进行修改。但是在项目中对代码进行了修改,就意味着要重新测试并部署。

@org.junit.Test
public void test() {
    //UserService userService = new UserService(); 
    UserServiceNew userServiceNew = new UserServiceNew();
    User user = new User("张三","123456");
    //userService.login(user);
    userServiceNew.login(user);
}

2.2 使用Spring模式完成业务逻辑

 此时就涉及解耦合,那么什么是耦合呢?

耦合:指定是代码之间的强联系关系,一方的改变就会影响到另一方

  • 不利于代码的维护
  • 将类硬编码在程序中

接下来就使用Spring模式再对上述业务逻辑进行操作。在测试的过程中,就不new Service对象了而是使用工厂模式去生产Service对象,这样可以解耦

创建一个工厂类

public class BeanFactory {
    public static UserService getUserService() {
        return new UserService();
    }
}

 此时利用工厂类再去创建UserService对象

@org.junit.Test
public void test() {
    //UserService userService = new UserService();
    UserService userService = BeanFactory.getUserService();
    User user = new User("张三","123456");
    userService.login(user);
}

这时候细心的同学可能就发现了,工厂类中也是new对象啊,那不还是有耦合。确实是这样的,接下来就对工厂类继续修改(由于测试流程是一致的,这里就不在展示测试过程)

public class BeanFactory {
    public static UserService getUserService() {
        // 这里使用反射创建对象
        UserService userService = null;
        try {
            Class clazz = Class.forName("com.gl.demo.UserService");
            userService = (UserService) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return userService;
    }
}

此时使用反射创建类对象大大降低了耦合,但是再细心一点的同学就会发现,那要是这个类名称变化了呢,这个代码还不是要修改 。说的对,接下来就是重头戏了,使用文件加载的方式加载类对象!

public class BeanFactory {
    // 创建文件对象
    private static Properties env = new Properties();

    // 利用静态代码块一次性的加载文件
    static {
        InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        try {
            env.load(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static UserService getUserService() {
        UserService userService = null;
        try {
            Class clazz = Class.forName(env.getProperty("userService"));
            userService = (UserService) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return userService;
    }
}

此时回看代码,耦合基本上就没有了,如果要添加类的话,也只需要更改文件中的类路径就行了

三、为什么使用Spring?

对于类对象,不只是单单的存在一个UserService,回看UserService方法,也是new了一个UserDao对象。肯定也是存在耦合的,这里肯定也要利用工厂类获取

此时在UserService中使用BeanFactory工厂类创建UserDao对象,并且在BeanFactory中创建对应的方法获取UserDao对象

public class BeanFactory {
    // 创建文件对象
    private static Properties env = new Properties();

    // 利用静态代码块一次性的加载文件
    static {
        InputStream inputStream =
                BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        try {
            env.load(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

     public static UserDao getUserDao() {
        UserDao userDao = null;
        try {
            Class clazz = Class.forName(env.getProperty("userDao"));
            userDao = (UserDao) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return userDao;
    }

    public static UserService getUserService() {
        UserService userService = null;
        try {
            Class clazz = Class.forName(env.getProperty("userService"));
            userService = (UserService) clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return userService;
    }
}

此时,问题又出现了,每当需要获取一个对象的时候我都要写一个方法,那这样的代码冗余不是非常高吗!此时就可以使用Object来返回对象解决此问题!

public class BeanFactory {
    // 创建文件
    private static Properties env = new Properties();

    // 利用静态代码块一次性的加载文件
    static {
        InputStream inputStream =
                BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        try {
            env.load(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 此时就利用参数获取想要创建的对象
    public static Object getBean(String key) {
        Object ret = null;
        try {
            Class clazz = Class.forName(env.getProperty(key));
            ret = clazz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return ret;
    }

//    public static UserService getUserService() {
//        UserService userService = null;
//        try {
//            Class clazz = Class.forName(env.getProperty("userService"));
//            userService = (UserService) clazz.newInstance();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return userService;
//    }
//
//    public static UserDao getUserDao() {
//        UserDao userDao = null;
//        try {
//            Class clazz = Class.forName(env.getProperty("userDao"));
//            userDao = (UserDao) clazz.newInstance();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return userDao;
//    }

}

对于之前的类对象获取也需要进行相应的处理,强制类型转化即可。

至此,所有的问题都已经解决完毕了!!! 从上面的过程可以发现,解耦的过程还是很复杂的,但是在Spring中已经包含了工厂的设计模式!并不需要我们去手动的写工厂类,我们只需要去使用Spring中的工厂类就可以了。Spring 框架提供了许多功能和特性,可以帮助开发人员快速构建企业应用程序。所以这也就是我们为什么要使用Spring进行项目开发的原因!

这里Spring的本质也就可以总结为:工厂!一个功能强大的工厂!至此Spring的学习正式开始

SpringTask是Spring框架中提供的一种用于在指定时间执行任务的调度框架。它可以定时执行任务、循环执行任务、以及在指定时间执行一次性任务等。 SpringTask的使用步骤如下: 1. 在Spring配置文件中添加Task命名空间和TaskExecutor线程池配置,如下所示: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> <task:executor id="taskExecutor" pool-size="5"/> <task:scheduler id="taskScheduler" pool-size="10"/> <!-- bean definitions go here --> </beans> ``` 其中,`task:executor`定义了一个线程池,用于执行任务;`task:scheduler`定义了一个调度器,用于调度定时任务。 2. 在Spring配置文件中定义一个定时任务,如下所示: ```xml <bean id="myTask" class="com.example.MyTask"/> <task:scheduled-tasks scheduler="taskScheduler"> <task:scheduled ref="myTask" method="run" cron="0 0/5 * * * ?"/> </task:scheduled-tasks> ``` 其中,`myTask`是一个简单的任务类,`cron`属性指定了任务的执行时间。 3. 启动Spring容器,Spring会自动启动定时任务,按照指定的时间执行任务。 除了定时任务外,SpringTask还支持按照一定的间隔时间执行任务、以及在指定时间执行一次性任务等。具体使用方式可以参考Spring官方文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值