JAVA配置&註解方式搭建簡單的SpringMVC先後臺交互系統

前面兩篇文章介紹了 基於XML方式搭建SpringMVC先後臺交互系統的方法,博文連接以下:
  http://www.cnblogs.com/hunterCecil/p/8252060.html
  http://www.cnblogs.com/hunterCecil/p/6924935.htmlhtml

本文重點介紹一下基於java配置+註解方式搭建系統的過程步驟。前端


1、摘要
  一、所需軟件列表:
    1) tomcat : apache-tomcat-7.0.54  服務端容器
    2) Intellij: Intellij IDEA 2016.3.1    開發工具  
    3) Syslog: SQLyog Community    數據庫工具
  2. 步驟簡述:
   1) 新建一個 Java 項目, 按下圖依次選擇:
     
   2) 項目目錄以下:
    
各目錄存儲文件以下:java

(1)java.com : 目錄下用於存放後臺代碼:mysql

    config: 配置啓動類
    controller: 應用層實現類
    dao: 數據訪問層的bean
    entity: 對象實體類
    service: 業務層bean, 具體的數據庫操做實現類
(2)resource:
    jdbc.properties: 數據庫配置
    log4j.properties: 日誌配置相關屬性
    users.sql: 建表語句web

(3)webapp: 客戶端展現相關文件spring

2、 相關配置文件
  1. web.xml配置(用於配置Spring 相關配置項:上下文、日誌、字符集、監聽器等經過配置文件加載,這裏只配置welcome-file-list及session-config)sql

<?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.propertiesapache

#日誌輸出級別
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.sqlapi

-- ----------------------------
-- 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類中咱們的配置類已經按順序加載過了。

4、 測試

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
相關文章
相關標籤/搜索