Spring入门(一)IOC

66 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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 )

小结与思考

控制反转之前,是由开发人员指定对象的生成,而控制反转之后,对象的生成不依赖于对象的使用,即不依赖于开发人员的构建。

低耦合:配置化、可扩展(插件化)、高度抽象(面向抽象编程、从而强依赖依赖于抽象对象);