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 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。
Spring是一个轻量级的JavaEE解决方案,整合众多优秀的设计模式
1. 广义概念
面向对象设计中,解决特定问题的经典代码
2. 狭义概念
G0F4人帮定义的23种设计模式:工厂、适配器、装饰器、门面、代理、模板...
1. 概念:通过工厂类,创建对象
User user = new User();
UserDAO userDAO = new UserDAOImpl();
2. 好处:解耦合
耦合:指定是代码间的强关联关系,一方的改变会影响到另一方
问题:不利于代码维护
简单:把接口的实现类,硬编码在程序中
UserService userService = new UserServiceImpl();
// 此时如果UserServiceImpl要换,则需要换其他与之相关联的代码(Servlet等也一起变)
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'}
*/
}
}
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文件的内容
# 特殊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
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
*/
}
}
问题:简单工厂会存在大量的代码冗余
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);
}
}
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);
}
Spring本质:工厂 ApplicationContext ( 配置文件: applicationContext.xml )
第一个Spring及日志整合