Spring学习笔记:引言及简单的工厂实现

Spring笔记汇总

引言及简单的工厂实现

    • 1、什么是spring
    • 2、EJB (Enterprise Java Bean )存在的问题
    • 3、什么是spring
      • 1、轻量级
      • 2、代码移植性高
      • 3、JavaEE的解决方案
      • 4、整合设计模式
    • 4、设计模式
    • 5、工厂设计模式
      • 5.1 什么是工厂设计模式
      • 5.2 简单工厂实现
        • BeanFactory的解耦合(反射工厂)
        • properties
        • TestSpring
      • 5.3 通用工厂设计
        • 通用工厂的代码
      • 5.4 通用工厂的使用方法
    • 6、总结

1、什么是spring

2002年,Rod Johnson撰写了一本名为《J2EE设计和开发》的书。本书主要概括了当时Java企业应用程序开发的现状以及指出了JavaEE规范中EJB框架的缺陷,并在书中基于普通Java类和设计模式提出了更为简单的解决方案(interface21)。同年在《J2EE Development Without EJB》一书中, 他进一步拓展了Interface21的代码,衍生而来了一个轻量级J2EE开发解决方案- -Spring。2004年3月在Sourceforge正式发布了Spring框架的第一个版本。 目前SpringFramework最新的版本为5.x

Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

2、EJB (Enterprise Java Bean )存在的问题

Spring学习笔记:引言及简单的工厂实现_第1张图片

3、什么是spring

Spring是一个轻量级的JavaEE解决方案,整合众多优秀的设计模式

1、轻量级

  • 对于运行环境是没有额外要求的
  • 开源 tomcat resion jetty
  • 收费 weblogic websphere

2、代码移植性高

  • 不需要实现额外接口

3、JavaEE的解决方案

Spring学习笔记:引言及简单的工厂实现_第2张图片

4、整合设计模式

  • 工厂
  • 代理
  • 模板
  • 策略

4、设计模式

1. 广义概念
面向对象设计中,解决特定问题的经典代码
2. 狭义概念
G0F4人帮定义的23种设计模式:工厂、适配器、装饰器、门面、代理、模板...

5、工厂设计模式

5.1 什么是工厂设计模式

1. 概念:通过工厂类,创建对象
        User user = new User();
        UserDAO userDAO = new UserDAOImpl();
2. 好处:解耦合
    耦合:指定是代码间的强关联关系,一方的改变会影响到另一方
    问题:不利于代码维护
    简单:把接口的实现类,硬编码在程序中
		UserService userService = new UserServiceImpl();
	// 此时如果UserServiceImpl要换,则需要换其他与之相关联的代码(Servlet等也一起变)

5.2 简单工厂实现

package com.company.basic;

import org.junit.Test;

public class TestSpring {

    /**
     * 测试:工厂类的解耦合
     */
    @Test
    public void test1() {
//        问题1:此时如果有一个新的UserServiceImplNew()实现类
//              UserService userService = new UserServiceImplNew();
//       此时需要经过编译和重新部署的过程,不符合面向对象的开闭原则  --->解决方法:BeanFactory
//              UserService userService = new UserServiceImpl();

        UserService userService = BeanFactory.getUserService(); // 此时由工厂来创建对象:实现解耦合

        // 登录
        userService.login("name", "password");

        // 注册
        User user = new User("me", "123456");
        userService.register(user);

        /*
        query User name = namepassword = password
        insert into user = User{name='me', password='123456'}
         */
    }
}

BeanFactory的解耦合(反射工厂)

package com.company.basic;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

public class BeanFactory {
    private static Properties env = new Properties();

    static {
        try (
            // 第一步: 获得IO输入流
            InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        ) {
            // 第二步: 文件内容  封装  Properties集合  key = userService  value = com.company.basic.UserServiceImpl
            env.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
    对象的创建方式:
        1.直接调用构造方法创建对象
            UserService userService = new UserServiceImpl();
        2.通过反射的形式创建对象解耦合
            Class clazz = Class. forName("com.company.basic.UserServiceImpl")
            UserService userService = (UserService)clazz.newInstance(); 【jdk9之前】
     */
    public static UserService getUserService() {

        UserService userService = null;

        try {
            // 问题3:此时传入的包名依旧是存在耦合   --->    通过读取配置文件进行调用
//            Class clazz = Class.forName("com.company.basic.UserServiceImpl");
            Class clazz = Class.forName(env.getProperty("userService"));
            userService = (UserService) clazz.getConstructor().newInstance();
        } catch (...) {
            ...
        }

        return userService;   // 问题2:工厂内部如何实现解耦合  --->  通过反射调用
    }

    /**
     * 同理对Dao层解耦
     * @return
     */
    public static UserDao getUserDao() {

        UserDao userDao = null;

        try {
            // 问题3:此时传入的包名依旧是存在耦合   --->    通过读取配置文件进行调用
//            Class clazz = Class.forName("com.company.basic.UserServiceImpl");
            Class clazz = Class.forName(env.getProperty("userDAO"));
            userDao = (UserDao) clazz.getConstructor().newInstance();
        } catch (...) {
            ...
        }

//        return new UserDaoImpl;		 // 问题2:工厂内部如何实现解耦合  --->  通过反射调用
        return userDao;  
    }
}

properties

#  Properties集合存储Properties文件的内容
#  特殊Map key=String value=String
#  Properties [userService = com.company.xxx.UserServiceImpl]
#  Properties.getProperty("userService")
#

userService = com.company.basic.UserServiceImpl

#userService = com.company.basic.UserServiceNewImpl

userDAO = com.company.basic.UserDao

TestSpring

package com.company.basic;

import org.junit.Test;

public class TestSpring {

    /**
     * 测试:工厂类的解耦合
     */
    @Test
    public void test1() {
//        问题1:此时如果有一个新的UserServiceImplNew()实现类
//              UserService userService = new UserServiceImplNew();
//       此时需要经过编译和重新部署的过程,不符合面向对象的开闭原则  --->解决方法:BeanFactory
//              UserService userService = new UserServiceImpl();

        UserService userService = BeanFactory.getUserService(); // 此时由工厂来创建对象:实现解耦合

        // 登录
        userService.login("name", "password");

        // 注册
        User user = new User("me", "123456");
        userService.register(user);

        /*
        query User name = namepassword = password
        insert into user = User{name='me', password='123456'}
         */
        
        /*
        新的实现类打印
        UserServiceNewImpl.login
        UserServiceNewImpl.register
         */
    }
}

5.3 通用工厂设计

问题:简单工厂会存在大量的代码冗余

Spring学习笔记:引言及简单的工厂实现_第3张图片

通用工厂的代码

BeanFactory

public class BeanFactory {
    private static Properties env = new Properties();

    static {
        try (
            // 第一步: 获得IO输入流
            InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
        ) {
            // 第二步: 文件内容  封装  Properties集合  key = userService  value = com.company.basic.UserServiceImpl
            env.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String key) {
        Object ret = null;
        try {
            Class clazz = Class.forName(env.getProperty(key));
            ret = clazz.getConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ret;
    }
}

UserServiceImpl

public class UserServiceImpl implements UserService {

    // 此时需要进行强制转换
    private UserDao userDao = (UserDao) BeanFactory.getBean("userDao");

    public void register(User user) {
        userDao.saveDao(user);
    }

    public void login(String name, String password) {
        userDao.queryUserByNameAndPassword(name,password);
    }
}

Test

package com.company.basic;

import org.junit.Test;

public class TestSpring {

    /**
     * 测试:工厂类的解耦合
     */
    @Test
    public void test1() {
		// 此时由工厂来创建对象:实现解耦合 ---> 也需要进行强制转换
        UserService userService = (UserService) BeanFactory.getBean("userService"); 

        // 登录
        userService.login("name", "password");

        // 注册
        User user = new User("me", "123456");
        userService.register(user);

    }
}

5.4 通用工厂的使用方法

1. 定义类型(类)
2. 通过配置文件的配置告知工厂(applicationContext.properties)
   key = value
3. 通过工厂获得类的对象
   Object ret = BeanFactort.getBean("key");

例子:

// 第一步
public class Person {
}

// 第二步
person = com.company.basic.Person
    
// 第三步
public void test(){
    Person person = (Person) BeanFactory.getBean("person");
    System.out.println(person);
}

6、总结

Spring本质:工厂	ApplicationContext 	( 配置文件: applicationContext.xml )

第一个Spring及日志整合

你可能感兴趣的:(spring)