一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情。
1.Spring简介
Spring是一个开源框架,它由Rod Johnson创建。它是为了解决企业应用开发的复杂性而创建的。
目前是JavaEE开发的灵魂框架。他可以简化JavaEE开发,可以非常方便整合其他框架,无侵入的进行功能增强。
Spring的核心就是 控制反转(IoC)和面向切面(AOP) 。
2.IOC控制反转
将获取对象的方式交给了 BeanFactory 。这种将控制权交给别人的思想,就可以称作:控制反转( Inverse of Control , IOC )
看下面代码演示
2.1 概念
控制反转,之前对象的控制权在类手上,现在反转后到了Spring手上。把自己创建资源、向环境索取资源变成环境将资源准备好,我们享受资源注入。
为了更好理解IOC举个例子 以javaweb创建一个项目
Dao与DaoImpl
public interface UserDao {
String getUserNameById(Integer id);
User getUserById(Integer id);
}
public class UserDaoImpl1 implements UserDao {
@Override
public String getUserNameById(Integer id) {
return "李四1";
}
@Override
public User getUserById(Integer id) {
return new User(1,"北京1",27);
}
}
Service与ServiceImpl
public interface UserService {
public void showUser();
public void showUser2();
public void showUser3();
}
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl1();
@Override
public void showUser() {
;
System.out.println(userDao.getUserById(1));
}
@Override
public void showUser2() {
System.out.println(userDao.getUserById(1));
}
@Override
public void showUser3() {
System.out.println(userDao.getUserNameById(1));
}
}
public class Demo {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.showUser();
}
}
存在的问题
现在可以正常运行,但是还是存在一些问题,比如需求发生了变化,UserDao写法需要变化,内部类也需要改变,因此我们需要把之前用到UserDao实现类的地方替换成新的实现类,至此我们就发现service的实现类和UserDao的实现类耦合在了一起,耦合性太强,代码维护和修改就比较麻烦,因此我们就需要引入IOC。
自制简易版IOC
代码中有注释,需要了解反射的一些知识
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean class="com.dao.impl.UserDaoImpl1" id="userDao"></bean>
</beans>
public class ClassPathXmlApplicationContext {
private static Map<String,Object> beanMap = new HashMap<>();
private String filePath;
public ClassPathXmlApplicationContext(String filePath){
this.filePath = filePath;
load();
}
private void load() {
try {
String path = ClassPathXmlApplicationContext.class.getClassLoader().getResource(filePath).getPath();
// 将上面的路径传进来,进行utf-8编码
path = URLDecoder.decode(path,"utf-8");
// Jsoup解析xml文件,将内容读取出来,封装成document
Document document = Jsoup.parse(new File(path), "utf-8");
// 获取Bean标签
Elements beans = document.getElementsByTag("bean");
if(beans!=null && beans.size()>0 ){
for (int i = 0; i < beans.size(); i++) {
//遍历所有的bean标签
Element bean = beans.get(i);
//获取 bean标签中的class和id值
String className = bean.attr("class");
String id = bean.attr("id");
//通过得到的bean标签中的class和id值,通过反射创建对应类的对象
Class<?> clazz = Class.forName(className);
Constructor<?> constructor = clazz.getConstructor();
Object obj = constructor.newInstance();
//把id作为key 创建出来的对象作为value存进map中
beanMap.put(id,obj);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据id从容器中获取对应的对象
* @param id
* @return
*/
public Object getBean(String id){
return beanMap.get(id);
}
}
public class Demo {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
UserDao userDao = (UserDao) classPathXmlApplicationContext.getBean("userDao");
System.out.println(userDao.getUserNameById(1));
}
}
IOC的思想
修改service中实现类的代码
public class UserServiceImpl implements UserService {
UserDao userDao = (UserDao) new ClassPathXmlApplicationContext("beans.xml").getBean("userDao");
@Override
public void showUser() {
;
System.out.println(userDao.getUserById(1));
}
@Override
public void showUser2() {
System.out.println(userDao.getUserById(1));
}
@Override
public void showUser3() {
System.out.println(userDao.getUserNameById(1));
}
}
至此耦合性就降低了,你只需要修改beans.xml文件中的class和id,内部是通过反射自己去创建对象。
这种将控制权交给别人的思想,就可以称作:控制反转( Inverse of Control , IOC )
小结与思考
控制反转之前,是由开发人员指定对象的生成,而控制反转之后,对象的生成不依赖于对象的使用,即不依赖于开发人员的构建。
低耦合:配置化、可扩展(插件化)、高度抽象(面向抽象编程、从而强依赖依赖于抽象对象);