• JAVA配置&注解方式搭建简单的SpringMVC前后台交互系统


    前面两篇文章介绍了 基于XML方式搭建SpringMVC前后台交互系统的方法,博文链接如下:
      http://www.cnblogs.com/hunterCecil/p/8252060.html
      http://www.cnblogs.com/hunterCecil/p/6924935.html

    本文重点介绍一下基于java配置+注解方式搭建系统的过程步骤。


    一、摘要
      1、所需软件列表:
        1) tomcat : apache-tomcat-7.0.54  服务端容器
        2) Intellij: Intellij IDEA 2016.3.1    开发工具  
        3) Syslog: SQLyog Community    数据库工具
      2. 步骤简述:
       1) 新建一个 Java 项目, 按下图依次选择:
         
       2) 项目目录如下:
        
    各目录存储文件如下:

    (1)java.com : 目录下用于存放后台代码:

        config: 配置启动类
        controller: 应用层实现类
        dao: 数据访问层的bean
        entity: 对象实体类
        service: 业务层bean, 具体的数据库操作实现类
    (2)resource:
        jdbc.properties: 数据库配置
        log4j.properties: 日志配置相关属性
        users.sql: 建表语句

    (3)webapp: 客户端展示相关文件

    二、 相关配置文件
      1. web.xml配置(用于配置Spring 相关配置项:上下文、日志、字符集、监听器等通过配置文件加载,这里只配置welcome-file-list及session-config)

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    	version="3.0" metadata-complete="false">
    
    	<!-- session超时 -->
    	<session-config>
    		<session-timeout>60</session-timeout>
    	</session-config>
    	<!-- 欢迎页面 -->;
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    	
    </web-app>
    

      2. jdbc. properties

    jdbc.driver = com.mysql.jdbc.Driver
    db.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
    db.username = root
    db.password = *****
    

      3. log4j.properties

    #日志输出级别
    log4j.rootLogger=INFO,stdout,other
    
    #设置stdout的日志输出控制台
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    #输出日志到控制台的方式,默认为System.out
    log4j.appender.stdout.Target = System.out
    #设置使用灵活布局
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    #灵活定义输出格式
    log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n
    
    #设置other的日志输出控制台
    log4j.appender.other=org.apache.log4j.RollingFileAppender
    #设置other的输出日志
    log4j.appender.other.File=/WEB-INF/logs/log.log
    #设置other的日志最大限制
    log4j.appender.other.MaxFileSize=1024KB
    #最多只保存20个备份文件
    log4j.appender.other.MaxBackupIndex=1000
    #输出INFO级别以上的日志
    og4j.appender.other.Threshold=INFO
    #设置使用灵活布局
    log4j.appender.other.layout=org.apache.log4j.PatternLayout
    #灵活定义输出格式
    log4j.appender.other.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %t %m %n
    

      4. uses.sql

    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` tinyint (20),
    	`name` varchar (90),
    	`age` tinyint (100),
      PRIMARY KEY (`id`),
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    insert into `user` (`id`, `name`, `age`) values('2','zhangsan','32');
    insert into `user` (`id`, `name`, `age`) values('3','lisi','33');
    insert into `user` (`id`, `name`, `age`) values('1','wangwu','12'); 

     5. config目录下文件:
      DatabaseConfig 

    @Configuration
    @EnableTransactionManagement
    public class DatabaseConfig {
        private static final Logger logger = Logger.getLogger(DatabaseConfig.class.getName());
    
        @Value("${jdbc.driver}")
        private String jdbcDriver;
    
        @Value("${db.url}")
        private String dbUrl;
    
        @Value("${db.username}")
        private String username;
    
        @Value("${db.password}")
        private String password;
    
        @Bean(destroyMethod = "close")
        public DataSource dataSource() {
            logger.info("mysql url:"+dbUrl);
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName(jdbcDriver);
            dataSource.setUrl(dbUrl);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        }
    
        @Bean
        public DataSourceTransactionManager txManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource());
            return sessionFactory.getObject();
        }
    }
    

     PropertiesConfig

    @Configuration
    @PropertySource(value={"classpath:jdbc.properties"})
    public class PropertiesConfig {
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }
    

     RootConfig

    @Configuration
    @ComponentScan(basePackages = {"com"})
    public class RootConfig {
    }
    

     WebConfig

    @Configuration
    @EnableWebMvc
    @EnableAspectJAutoProxy
    @EnableTransactionManagement
    @ComponentScan("com.controller")
    @MapperScan("com.dao")
    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;
        }
    
        @Bean
        public StringHttpMessageConverter stringHttpMessageConverter(){
            return new StringHttpMessageConverter();
        }
    
        @Bean
        public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
            return new MappingJackson2HttpMessageConverter();
        }
    
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.add(stringHttpMessageConverter());
            converters.add(mappingJackson2HttpMessageConverter());
            super.configureMessageConverters(converters);
        }
    
        /**
         * 启用spring mvc 的注解
         */
        public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
            configurer.enable();
        }
    }
    

      WebAppInitializer

    /**
     * 配置SpringMVC需要添加DispatchServlet ,
     * DispatcherServlet主要负责前端调用URL的分发,
     * 它在Web容器初始化的时候被注册。
     * 这里配置中继承了DispatchServlet 的一个抽象类AbstractAnnotationConfigDispatcherServletInitializer ,
     * 此抽象类的父类在实例化的时候会注册一个DispatchServlet到容器中
     * 这里配置了容器初始化时需要加载的配置类 RootConfig,PropertiesConfig  和 WebConfig
     */
    public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        /** 应用上下文、配置文件读取,数据库配置*/
        @Override
        protected Class<?>[] getRootConfigClasses() {
            System.out.println("======1.应用上下文、配置文件读取,数据库配置 load ================");
            return new Class<?>[]{RootConfig.class, PropertiesConfig.class, DatabaseConfig.class};
        }
    
        /* web上下文  */
        @Override
        protected Class<?>[] getServletConfigClasses() {
            System.out.println("======2.web上下文 load ================");
            return new Class<?>[]{WebConfig.class};
        }
    
        /*  DispatcherServlet的映射路径 */
        @Override
        protected String[] getServletMappings() {
            System.out.println("======3.DispatcherServlet的映射路径 load ================");
            return new String[]{"/"};
        }
    
        /* 注册过滤器,映射路径与DispatcherServlet一致,路径不一致的过滤器需要注册到另外的WebApplicationInitializer中*/
        @Override
        protected Filter[] getServletFilters() {
            CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
            characterEncodingFilter.setEncoding("UTF-8");
            characterEncodingFilter.setForceEncoding(true);
            return new Filter[]{characterEncodingFilter};
        }
    }
    

      6.  controller-TestController

    @Controller
    public class TestController {
    
        @Autowired
        @Qualifier("userService")
        private UserService userService;
    
        @RequestMapping(value = "/test", method = RequestMethod.GET)
        public String test() {
            return "test";
        }
    
        @RequestMapping(value = "/getuser/{username}", method = RequestMethod.GET)
        @ResponseBody
        public User getUser(@PathVariable String username) {
            return  userService.loadUserByUsername(username);
        }
    }
    

      7. dao-UserDao

    @Controller
    public class TestController {
    
        @Autowired
        @Qualifier("userService")
        private UserService userService;
    
        @RequestMapping(value = "/test", method = RequestMethod.GET)
        public String test() {
            return "test";
        }
    
        @RequestMapping(value = "/getuser/{username}", method = RequestMethod.GET)
        @ResponseBody
        public User getUser(@PathVariable String username) {
            return  userService.loadUserByUsername(username);
        }
    }
    

      8. entity-User

    public class User {
        private Integer id;
        private String name;
        private Integer age;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

      9. log-logAspect

    @Component
    @Aspect
    public class LogAspect {
        private static final Logger logger = Logger.getLogger(LogAspect.class.getName());
    
        @Pointcut("execution(* com.controller.*.*(..))")
        public void performance() {
        }
    
        @Before("performance()")
        public void optionBefore(JoinPoint joinPoint){
            System.out.println("@Before开始执行"+joinPoint.getSignature().getDeclaringTypeName() +
                    "." + joinPoint.getSignature().getName());
        }
    
        @After("performance()")
        public void optionAfter(JoinPoint joinPoint){
            System.out.println("@After结束执行"+joinPoint.getSignature().getDeclaringTypeName() +
                    "." + joinPoint.getSignature().getName());
        }
        @Around("performance()")
        public Object optionAround(ProceedingJoinPoint pjp) throws Throwable {
            Object retVal = null;
            System.out.println("@Around start..");
            try {
                retVal = pjp.proceed();
            } catch (Throwable ex) {
                System.out.println("error in @Around");
                throw ex;
            }
            System.out.println("@Around end");
            return retVal;
        }
    
        @AfterReturning(pointcut = "performance()", returning = "returnValue")
        public void optionAfterReturn(JoinPoint joinPoint, Object returnValue) {
            System.out.println("@AfterReturning:目标方法为:" +
                    joinPoint.getSignature().getDeclaringTypeName() +
                    "." + joinPoint.getSignature().getName());
            System.out.println("@AfterReturning:参数为:" +
                    Arrays.toString(joinPoint.getArgs()));
            System.out.println("@AfterReturning:返回值为:" + returnValue);
            System.out.println("@AfterReturning:被织入的目标对象为:" + joinPoint.getTarget());
    
        }
    
        @AfterThrowing(pointcut = "performance()", throwing = "e")
        public void optionError(JoinPoint joinPoint, Throwable e) {
            logger.log(Level.WARNING,"异常方法:{" + joinPoint.getTarget().getClass().getName() +
                    "." + joinPoint.getSignature().getName() + "}" +
                    "异常类型:{" + e.getClass().getName() + "}" +
                    "异常信息:{" + e.getMessage() + "}" +
                    "参数:{" + Arrays.toString(joinPoint.getArgs()) + "}", e);
        }
    }
    

      10. service-UserService

    public interface UserService {
    
        User loadUserByUsername(String username);
    
        void saveUser(User user);
    }
    

       11. service-impl-UserServiceImpl

    @Service("userService")
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private UserDao userDao;
    
        @Transactional(readOnly = true)
        public User loadUserByUsername(String username) {
            return userDao.loadUserByUsername(username);
        }
    
        @Transactional
        public void saveUser(User user) {
            userDao.saveUser(user);
        }
    }
    

      12. maven 对应的pom文件如下:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com</groupId>
        <artifactId>springJavaConfig</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>springJavaConfig Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.6</java.version>
        </properties>
        <dependencies>
            <dependency>
                <!--Unit Test -->
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
            <!-- Servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>provided</scope>
            </dependency>
            <!-- SpringMVC -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.3.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.3.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.6</version>
            </dependency>
        <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.5</version> </dependency> </dependencies> <build> <finalName>springJavaConfig</finalName> </build> </project>

     三. 启动过程打印日志:

    Connected to server
    [2018-01-17 10:47:20,950] Artifact springJavaConfig:war exploded: Artifact is being deployed, please wait...
    一月 17, 2018 10:47:23 上午 org.apache.catalina.startup.TldConfig execute
    信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    ======1.应用上下文、配置文件读取,数据库配置 load ================
    ======2.web上下文 load ================
    ======3.DispatcherServlet的映射路径 load ================
    一月 17, 2018 10:47:24 上午 org.springframework.web.context.ContextLoader initWebApplicationContext
    信息: Root WebApplicationContext: initialization started
    一月 17, 2018 10:47:24 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
    信息: Refreshing Root WebApplicationContext: startup date [Wed Jan 17 10:47:24 CST 2018]; root of context hierarchy
    一月 17, 2018 10:47:24 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
    信息: Registering annotated classes: [class com.config.RootConfig,class com.config.PropertiesConfig,class com.config.DatabaseConfig]
    一月 17, 2018 10:47:25 上午 com.config.DatabaseConfig dataSource
    信息: mysql url:jdbc:mysql://10.42.120.201:3306/test?useUnicode=true&characterEncoding=UTF-8
    一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
    信息: Mapped "{[/test],methods=[GET]}" onto public java.lang.String com.controller.TestController.test()
    一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
    信息: Mapped "{[/getuser/{username}],methods=[GET]}" onto public com.entity.User com.controller.TestController.getUser(java.lang.String)
    一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
    信息: Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
    信息: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Wed Jan 17 10:47:24 CST 2018]; root of context hierarchy
    一月 17, 2018 10:47:26 上午 org.springframework.web.context.ContextLoader initWebApplicationContext
    信息: Root WebApplicationContext: initialization completed in 2370 ms
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.DispatcherServlet initServletBean
    信息: FrameworkServlet 'dispatcher': initialization started
    一月 17, 2018 10:47:26 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
    信息: Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Wed Jan 17 10:47:26 CST 2018]; parent: Root WebApplicationContext
    一月 17, 2018 10:47:26 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
    信息: Registering annotated classes: [class com.config.WebConfig]
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
    信息: Mapped "{[/test],methods=[GET]}" onto public java.lang.String com.controller.TestController.test()
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
    信息: Mapped "{[/getuser/{username}],methods=[GET]}" onto public com.entity.User com.controller.TestController.getUser(java.lang.String)
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
    信息: Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
    信息: Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Wed Jan 17 10:47:26 CST 2018]; parent: Root WebApplicationContext
    一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.DispatcherServlet initServletBean
    信息: FrameworkServlet 'dispatcher': initialization completed in 356 ms
    [2018-01-17 10:47:26,774] Artifact springJavaConfig:war exploded: Artifact is deployed successfully
    [2018-01-17 10:47:26,775] Artifact springJavaConfig:war exploded: Deploy took 5,825 milliseconds 

    可以看到,WebAppInitializer类中我们的配置类已经按顺序加载过了。

    四、 测试

    url 输入 http://localhost:8080/getuser/zhangsan,可以查看切面部分打印日志如下:

    @Around start..
    @Before开始执行com.controller.TestController.getUser
    @Around end
    @After结束执行com.controller.TestController.getUser
    @AfterReturning:目标方法为:com.controller.TestController.getUser
    @AfterReturning:参数为:[zhangsan]
    @AfterReturning:返回值为:com.entity.User@182bab1a
    @AfterReturning:被织入的目标对象为:com.controller.TestController@24b0c989
    

     

  • 相关阅读:
    正则如何匹配div下的所有<li>标签?
    日历
    生成一定数量的不重复随机数
    PHP微信红包的算法实现探讨
    Flask 快速使用 —— (1)
    Django rest framework(8)---- 视图和渲染器
    Django 组件之 ----- content-type
    Django rest framework(7)----分页
    Django rest framework(6)----序列化(2)
    Django rest framework(5)----解析器
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/8302783.html
Copyright © 2020-2023  润新知