基于java Config 配置 spring+springmvc+hibernate

Isabell37G 8年前
   <p>时代在不断进步,大量基于xml的配置所带来的弊端也显而易见,在XML配置和直接注解式配置之外还有一种有趣的选择方式-JavaConfig,它是在Spring 3.0开始从一个独立的项目并入到Spring中的。它结合了XML的解耦和JAVA编译时检查的优点。JavaConfig可以看成一个XML文件,只不过是使用Java编写的。现在下面为大家展示如何编写基于java Config 配置 spring+springmvc+hibernate。</p>    <p>项目是在intellj IDE 下创建的maven项目,目录如下</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4491328722d3dc5214a9b7d543f6a838.png"></p>    <p>按照传统的方式,像DispatchServlet这样的Servlet会配置在web.xml文件中,但是借助Servlet3规范和Spring3.1增强,我们可以使用java将DispatchServlet配置在Servlet容器中,下面展示初始化类文件</p>    <pre>  <code class="language-java">public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {      //指定配置类      @Override      protected Class<?>[] getRootConfigClasses() {          return new Class<?>[] { RootConfig.class };      }        @Override      protected Class<?>[] getServletConfigClasses() {          return new Class<?>[] { WebConfig.class };      }            //将DispatchServlet映射到“/”      @Override      protected String[] getServletMappings() {          return new String[] { "/" };      }        @Override      protected void customizeRegistration(ServletRegistration.Dynamic registration) {      new MultipartConfigElement("/temp",2097152,4194304,0);      }    }  </code></pre>    <pre>  <code class="language-java">创建WebInitializer需要继承AbstractAnnotationConfigDispatcherServletInitializer,因为继承该类的任意类都会自动地配置DispatchServlet和Spring应用上下文,Spring的应用上下文会位于应用程序的Servlet上下文之中。          </code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8f5a8a6e1cd326d359379773a6e76440.png"></p>    <p>我们可以看到底层的AbstractAnnotationConfigDispatcherServletInitializer拓展和实现了WebApplicationInitializer,在Servlet3 环境中,容器会在类路径中查找实现了javax.servlet.ServletContainerInitializer接口的类,并将该类来配置Servlet容器,而spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又会查找实现了WebApplicationInitializer的类并将配置的任务交给他们来完成,所以当我们WebInitializer拓展了AbstractAnnotationConfigDispatcherServletInitializer ,同时就实现了WebApplicationInitializer,因此当部署到Servlet3.0容器中的时候,容器就会自动发现他,并用它来配置Servlet上下文。</p>    <p>WebInitializer中要求DispatchServlet加载应用上下文时,使用定义在WebConfig配置类中的bean。</p>    <p>在使用xml配置spring的时候,必须配置spring监听器,也是就ContextLoaderListener,然而很多人不知道的是,ContextLoaderListener会创建spring web 应用中的另一个上下文。</p>    <p>我们希望DispatchServlet加载包含Web组件的bean,如控制器、视图解析器以及处理器映射,而ContextLoaderListener要加载应用中的其他bean,这些bean通常是驱动应用后端的中间层和数据层组件。</p>    <p>也就是说WebConfig的类中会用来定义DispatcherServlet应用上下文的bean,RootConfig的类中会用来配置ContextLoadListener创建的上下文的bean</p>    <pre>  <code class="language-java">@Configuration  @EnableWebMvc //注解驱动springMVC 相当于xml中的<mvc:annotation-driven>  @ComponentScan("scau.zzf.web")//启用组件扫描  public class WebConfig extends WebMvcConfigurerAdapter {      @Bean      public ViewResolver viewResolver(){          InternalResourceViewResolver resolver=                  new InternalResourceViewResolver();          resolver.setPrefix("/WEB-INF/views/");          resolver.setSuffix(".jsp");          resolver.setExposeContextBeansAsAttributes(true);          return resolver;      }      //配置静态资源的处理,要求DispatchServlet对静态资源的请求转发到servlet容器中默认的Servlet上      @Override      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {          configurer.enable();      }    }  </code></pre>    <pre>  <code class="language-java">@Configuration  @Import(HibernateConfig.class)//导入Hibernate配置文件  @ComponentScan(basePackages={"scau.zzf"},          excludeFilters={                  @ComponentScan.Filter(type= FilterType.CUSTOM, value=RootConfig.WebPackage.class)          }  )  public class RootConfig {      //扫描除了web以外的所有包      public static class WebPackage extends RegexPatternTypeFilter {          public WebPackage() {              super(Pattern.compile("scau.zzf\\.web"));          }      }    }  </code></pre>    <p>HbernateConfig 如下</p>    <pre>  <code class="language-java">@Configuration  @PropertySource(          value={"classpath:ds/ds-jdbc.properties"},          ignoreResourceNotFound = true)//加载在resources下的ds-jdbc.properties  public class HibernateConfig {      @Value("${jdbc.driverClassName}")      private String driverClassName;      @Value("${jdbc.url}")      private String jdbcURL;      @Value("${jdbc.username}")      private String username;      @Value("${jdbc.password}")      private String password;      //配置sessionFactory      @Bean      public SessionFactory sessionFactoryBean() {          try {              LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();              lsfb.setDataSource(dataSource());              //扫描实体类              lsfb.setPackagesToScan("scau.zzf.entity");              Properties props = new Properties();              //设置方言 ,采用的是MySql              props.setProperty("dialect", "org.hibernate.dialect.MySQLDialect");              lsfb.setHibernateProperties(props);              lsfb.afterPropertiesSet();              SessionFactory object = lsfb.getObject();              return object;          } catch (IOException e) {              return null;          }      }      //配置DataSource      @Bean      public DataSource dataSource(){          BasicDataSource ds=new BasicDataSource();          ds.setDriverClassName(driverClassName);          ds.setUrl(jdbcURL);          ds.setUsername(username);          ds.setPassword(password);            return ds;      }    }  </code></pre>    <p>实体类如下</p>    <pre>  <code class="language-java">@Entity  @Table(catalog = "hibernate",name = "users")  public class User {      @Column      private String username;      @Column      private String password;      @Column      private String sex;      @Column      private String address;      @Column      private int enabled;        //GeneratedValue覆盖@id的默认访问策略      @Id      @GeneratedValue(strategy = GenerationType.IDENTITY)  //    @GenericGenerator是在hibernate中定义的,使用hibernate内置的各种主键生成粗略生成主键值  //    @GenericGenerator(name = "hibernate-uuid",strategy = "uuid")  //    @GeneratedValue(generator = "hibernate-uuid")      private int id;        public int getEnabled() {          return enabled;      }        public void setEnabled(int enabled) {          this.enabled = enabled;      }        public String getAddress() {          return address;      }        public void setAddress(String address) {          this.address = address;      }        public String getSex() {          return sex;      }        public void setSex(String sex) {          this.sex = sex;      }        public String getUsername() {          return username;      }        public void setUsername(String username) {          this.username = username;      }        public int getId() {          return id;      }        public void setId(int id) {          this.id = id;      }        public String getPassword() {          return password;      }        public void setPassword(String password) {          this.password = password;      }  }  </code></pre>    <p>在Test的环境下进行测试</p>    <pre>  <code class="language-java">@RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration(classes = {WebConfig.class, RootConfig.class})  @WebAppConfiguration  public class ServiceTest {            @Autowired      private UserService userService;      @Test      public void userServiceTest(){            User user=userService.findUser(1);          System.out.println(user.getUsername());      }    }  </code></pre>    <p>在test的环境下,类上的三个注解是一定要配置的,不然会出错。</p>    <p> </p>    <p> </p>    <p>来自:http://www.cnblogs.com/xxzhuang/p/5861231.html</p>    <p> </p>