学习spring的第4天

关于老式的spring+mybatis整合,使用了druid连接池,还使用了mybatis-spring依赖(用于整合的),但是这个依赖本身就使用了spring-jdbc的某些类来处理事务方面的内容,所以还需要额外再添加一个spring-jdbc依赖。

以前的mybatis是通过SqlSessionFactoryBuilder().build()创建出SqlSessionFactory,再调用openSession(true)创建出一个能够自动提交事务的sqlSession,再调用getMapper()得到一个dao类。而现在主要是通过spring的xml文件配置注入依赖。

1.原本的sqlSessionFactoryBuilder().build()在xml文件中改变成配置SqlSessionFactoryBean类的<bean>,有用到dataSource的set方法,获得了sqlSessionFactory对象(在spring容器加载的时候).

2.通过MapperFacotryBean类,这个类本身有一个setMapperInterface,其继承的SqlSessionDaoSupport类有一个setSessionFactory方法,通过在<bean>中配置这两个属性就可以得到一个dao类的对象(向上转型为接口的xxDao)

3.第二步已经把dao类得到了,再就是配置service,使用dao。

4.基本上的<bean>已经配置好了,但是为了方便获取ApplicationContext,也不是说方便,只是ApplicationContext如果通过每次在每个Servlet都new出来,然后又被垃圾回收销毁,而其又管理了多个<bean>,这样子耗时效率低下,也违背了被管理的<bean>的单例,通过监听器就在整个进程中获取一个ApplicationContext,当然你也可以不通过监听器而是直接写一个单例模式也是可以的。在Servlet下创建了一个上下文监听器,在tomcat启动时调用contextInitialized方法创建出一个ApplicationContexxt,具体代码如下:

public class InitializationListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        // 这里是在web.xml文件下写了一个<context-param>设置了spring.xml的文件名,方便不过过java代                     码改动  
        String configFile = servletContext.getInitParameter("configFile");
        ApplicationContext context = new ClassPathXmlApplicationContext(configFile);
        // 最好还是不要使用魔法值吧,context
        servletContext.setAttribute("context", context);
    }
    // 下方的销毁方法没有内容,无视
}    

  同时为了获取到这个context,还写了一个类实现spring的ApplicationContextAware接口(实现了Aware的接口,只要在spring配置好<bean>,其中的set方法都会自动装配,应该是,我不是很确定),set方法中设置了ApplicationContext的赋值,同时额外写一个了方法getBean,直接通过该类调用,就不需要ApplicationContext.getBean

public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static <T> T getBean(String name, Class<T> clz) {
        return context.getBean(name, clz);
    }
}

  5.但是监听器的启动需要在web.xml文件中配置

<listener>
        <listener-class>com.web.listener.InitializationListener</listener-class>
    </listener>

  而实现了ApplicationContextAware接口的类要被自动装配还需要配置一个<bean>,以自动装配调用set方法,设置了ApplicationContext对象,才能用到getBean,而不会报空指针异常。

applicationConfig.xml如下,最后一个<bean>是自动装配它自己的类的set方法,不用写id

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/demo"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="dao" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.dao.DeptDao"></property>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>

    <bean id="service" class="com.service.impl.DeptServiceImpl">
        <property name="deptDao" ref="dao"></property>
    </bean>

    <bean class="com.web.listener.ApplicationContextHolder"></bean>

  6.如此,dao模块就只需要写一个接口就行了,在方法上通过注解使用sql语句,service模块在impl类上设置一个dao的字段和对应的set方法。而Servlet中通过代码ApplicationHolder.getBean("service", XXX.class);就可以直接获取到service对象。

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        DeptService service =  ApplicationContextHolder.getBean("service", DeptService.class);
        List<Dept> depts = service.queryAll();
        req.setAttribute("depts", depts);
        req.getRequestDispatcher("WEB-INF/home.jsp").forward(req, resp);
    }

  

猜你喜欢

转载自www.cnblogs.com/woyujiezhen/p/11725229.html