跳至主要內容

Spring基础

晨光-向大约 4 分钟JavaSpringJavaSpring

Spring基础

1. spring优势

  1. 方便解耦,简化开发
    • 通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
  2. AOP 编程的支持
  3. 声明式事务的支持
  4. 方便程序的测试
  5. 方便集成各种优秀框架
  6. 降低 JavaEE API 的使用难度

2. spring体系结构

1. spring中文文档

spring中文文档open in new window

3. 入门JDBC操作 程序解耦

/**
 * @Author: CHGGX
 * @Description: <h1> 程序耦合 </h1>
 * 耦合: 程序间的依赖关系
 *      1. 类之间依赖
 *      2. 方法之间的依赖
 *  解耦: 降低程序间的依赖
 *
 *  开发过程应做到:
 *      编译期不依赖,运行期才依赖
 *  解耦思路:
 *      1. 使用反射来创建对象,避免使用new关键字
 *      2. 通过读取配置文件来获取要创建的对象全权限定类名
 *
 */
public class JdbcDemo01 {

    public static void main(String[] args) throws Exception {

        // 1. 注册驱动
//        DriverManager.registerDriver(new com.mysql.jdbc.Driver());

       Class.forName("new com.mysql.jdbc.Driver()");
        // 2. 获取连接
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/spring_jdbc",
                "root",
                "root"
        );
        // 3. 获取操作数据库的与处理对象
        PreparedStatement pstm = conn.prepareStatement("select * from account");
        // 4. 执行SQL,得到结果
        ResultSet resultSet = pstm.executeQuery();
        // 5. 遍历结果
        while (resultSet.next()) {
            System.out.println(resultSet.getString("name"));
        }
        // 6. 关闭流
        resultSet.close();
        pstm.close();
        conn.close();

    }

}

4. 解耦合

1. 配置文件

  • bean.properties
accountService=com.chggx.service.impl.AccountServiceImpl
accountDao=com.chggx.dao.impl.AccountDaoImpl

2. 业务逻辑

1. dao层
  • AccountDao
public interface AccountDao {

    /**
     * 模拟保存账户
     */
    void saveAccount();
}
  • AccountDaoImpl
public class AccountDaoImpl implements AccountDao {

    /**
     * 模拟保存账户
     */
    @Override
    public void saveAccount() {
        System.out.println("save success...");
    }
}
2. service
  • AccountService
public interface AccountService {

    /**
     * 模拟保存账户
     */
    void saveAccount();

}
  • AccountServiceImpl

    使用factory工厂的方式获取对象

public class AccountServiceImpl implements AccountService {

    /**
     * 普通方式 (耦合度高)
     */
//    private final AccountDao accountDao = new AccountDaoImpl();

    /**
     * 解耦合
     */
    private final AccountDao accountDao = (AccountDao) BeanFactory.getBean("accountDao");

    /**
     * 模拟保存账户
     */
    @Override
    public void saveAccount() {
        accountDao.saveAccount();
    }
}
3. AccountController
  • 解耦合 通过工厂的方式创建对象,实现程序间的解耦合
public class AccountController {

    /**
     * 模拟保存账户
     */
    public static void main(String[] args) {
        // 普通方式 (耦合度高)
      /*  AccountService service = new AccountServiceImpl();
        service.saveAccount();*/

        // 解耦合
        AccountService service = (AccountService) BeanFactory.getBean("accountService");
        service.saveAccount();
    }

}

3. 工厂模式解耦

  • 使用单例,每个对象只创建一次
/**
 * @Author: CHGGX
 * @Date: 2020/04/28 22:14
 * @Description: <h1> 一个创建Bean对象的工厂(解耦合) </h1>
 * Bean: 在计算机英语中,有可重用组件的含义
 * JavaBean: java语言编写的可重用组件
 * 1. JavaBean > 实体类
 * 2. 它就是创建我们的service和dao对象的
 * 解决:
 * 1. 需要一个配置文件来配置我们的service和dao
 * 配置内容: 1) 唯一标识=权限定类名
 * 2. 通过读取配置文件中的内容,反射创建对象
 * <p>
 * 配置文件形式:
 * 1. xml
 * 2. properties: 推荐
 */
public class BeanFactory {

    /**
     * 定义一个Properties对象
     */
    private static Properties props;

    /**
     * 定义一个Map,用于存放我们要创建的对象,我们称之为容器
     */
    private static Map<String, Object> beans;

    // 使用静态代码块Properties对象赋值
    static {
        try {
            // 1. 实例化对象
            props = new Properties();
            // 获取"bean.properties"文件的流对象
            // 获取Class对象 类名.class
            InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            // 加载配置文件
            props.load(is);

            //2. 实例化容器 [单例.只创建一次]
            beans = new HashMap<String, Object>();
            // 2.1 取出配置文件中所有的key
            Enumeration<Object> keys = props.keys();
            // 2.2 遍历枚举
            while (keys.hasMoreElements()) {
                // 2.2.1 去除每个key
                String key = (String) keys.nextElement();
                // 2.2.2 根据key获取值(类的权限定类名)
                String beanPath = (String) props.get(key);
                // 2.3 反射创建对象
                Object value = Class.forName(beanPath).newInstance();
                // 2.4 把key和value存入容器中(Map集合)
                beans.put(key, value);
            }
        } catch (Exception e) {
            // 错误 error子类
            throw new ExceptionInInitializerError("Properties init error !");
        }
    }

    /**
     * 改进: Bean只创建一次,(创建的对象存入容器中.此处指Map集合)
     *
     * @param beanName Bean的名称
     * @return Bean的对象
     */
    public static Object getBean(String beanName) {
        // 根据Bean的名称从容器中获取Bean的对象
        return beans.get(beanName);
    }

    /**
     * 根据Bean的名称获取Bean的对象 [此处是多例,每次都创建对象]
     *
     * @param beanName Bean的名称
     * @return Bean的对象
     */
//    public static Object getBean(String beanName) {
//        Object bean = null;
//        try {
//            String beanPath = props.getProperty(beanName);
//            // 获取Class对象 Class.forName("权限定类名")
//            // Constructor创建对象  T newInstance(Object... initargs)
//            bean = Class.forName(beanPath).newInstance();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return bean;
//    }

}