Spring快速上手

Spring快速上手

    Spring是分层的Java平台应用一站式的轻量级开源框架,以反转控制(Inversion of Control,IoC)和面向切面编程(Aspect Oriented Programming,AOP)为内核,提供了展现层SpringMVC、持久层SpringJDBC以及业务层事务管理等众多企业级应用技术,此外Spring还整合了中国第三方框架和类库。

    Spring给我们带来以下几个好处:

  • 方便解耦,简化开发。通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。

  • AOP编程的支持。通过Spring提供的AOP功能,用户可以方便地进行面向切面编程

  • 声明式事务。在Spring中,用户可以从单调烦闷的事务管理代码中解脱出来,通过声明式事务灵活地进行事务管理,提高开发效率和质量

  • 方便程序的测试。可以用非容器依赖的编程方式进行所有的测试工作。

  • 方便集成各种优秀的框架。Spring是非入侵是框架,能够整合其他优秀框架,如Struts、Hibernate、Quartz等

  • 降低JavaEEAPI的使用难度。Spring为JavaEE API(如JDBC、JavaMail和JMS等)提供了一个薄薄的封装层,通过Spring的简易封装,大大降低了这些JavaEE API的使用难度

  • Spring是开源项目,并且是源码是Java技术的最佳实践规范。

    Spring的组成:IoC、AOP、数据访问和继承、Web及远程调用以及测试框架。

  • IoC,Spring核心模块实现了IoC的功能,它将类和类之间的依赖从代码中脱离出来,用配置的方式进行依赖关系描述,由IoC容器负责依赖类之间的创建、拼接、管理和获取等工作。BeanFactory接口是Spring框架的核心接口,它实现了容器的许多核心功能。Context模块构建于BeanFactory之上,扩展了BeanFactory的功能。提供了邮件服务、任务调度以及JNDI定位、远程访问等。ApplicationContext是Context模块的核心接口。

  • AOP模块,AOP是进行横切逻辑编程的思想。在AOP模块里,Spring提供了满足AOP Alliance规范的实现,此外和整合了AspectJ这种AOP语言级的框架。

  • 数据访问和集成。任何应用程序的核心问题都是对数据的访问和操作。数据有很多表现形式,如数据表、XML、消息等。Spring站在DAO的抽象层面,简历了一套面向DAO层统一的异常体系。其次,Spring通过模板化技术对各种数据访问技术进行了薄层封装,将模式化的代码隐藏起来,是数据访问的程序得到大幅简化。这样Spring就建立起了和数据形式及访问技术无关的统一的DAO层,借助AOP技术,Spring提供了声明式事务的功能。

  • Web及远程访问。Spring提供了MVC,SpringMVC类似于StrutsMVC框架。此外Spring在远程访问以及WebService上提供了很多著名框架的整合。

本章将通过一个登陆示例来演示SpringMVC。

1、准备工作,创建数据库和数据表

DROP DATABASE IF EXISTS spring_src;
CREATE DATABASE spring_src DEFAULT CHARACTER SET utf8;
CREATE USER 'spring_src'@'localhost' IDENTIFIED BY 'spring_src';
GRANT ALL ON spring_src.* TO 'spring_src'@'localhost';
USE spring_src;

##创建用户表
CREATE TABLE t_user (
   user_id   INT AUTO_INCREMENT PRIMARY KEY,
   user_name VARCHAR(30),
   password  VARCHAR(32),
   last_visit datetime,
   last_ip  VARCHAR(23)
)ENGINE=InnoDB; 

##创建用户登录日志表
CREATE TABLE t_login_log (
   login_log_id  INT AUTO_INCREMENT PRIMARY KEY,
   user_id   INT,
   ip  VARCHAR(23),
   login_datetime datetime
)ENGINE=InnoDB; 

##插入初始化数据
INSERT INTO t_user (user_name,password) 
             VALUES('admin','123456');
COMMIT;

2、创建的工程如下:

wKiom1da4x2j47gUAAAVN_NJxnE660.png-wh_50

maven项目sprProject的主目录的pom文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.smart</groupId>
    <artifactId>chapter</artifactId>
    <packaging>pom</packaging>
    <version>3.1-SNAPSHOT</version>
    <name>Spring3.1 </name>
    <description>Spring3.1</description>
    <properties>
        <file.encoding>UTF-8</file.encoding>
        <java.version>1.6</java.version>
        <spring.action.version>3.1-SNAPSHOT</spring.action.version>
        <org.springframework.version>3.1.1.RELEASE</org.springframework.version>
        <mysql.version>5.1.6</mysql.version>
        <commons-dbcp.version>1.2.2</commons-dbcp.version>
        <aspectjweaver.version>1.6.9</aspectjweaver.version>
        <apache.commons.version>1.1.1</apache.commons.version>
        <commons-collections.version>3.2.1</commons-collections.version>
        <javassist.version>3.9.0.GA</javassist.version>
        <commons-beanutils.version>1.8.3</commons-beanutils.version>
        <ehcache.version>1.6.2</ehcache.version>
        <hibernate.version>3.6.10.Final</hibernate.version>
        <hibernate-validator.version>4.0.2.GA</hibernate-validator.version>
        <slf4j-jdk14.version>1.6.1</slf4j-jdk14.version>

        <commons-fileupload.version>1.2.1</commons-fileupload.version>
        <jsp-api.version>2.0</jsp-api.version>
        <servlet-api.version>2.5</servlet-api.version>
        <jstl.version>1.2</jstl.version>
        <standard.version>1.1.2</standard.version>
        <freemarker.version>2.3.8</freemarker.version>
        <jetty.version>6.1.5</jetty.version>

        <mockito-all.version>1.8.5</mockito-all.version>
        <junit.version>4.9.0</junit.version>
        <testng.version>6.3.1</testng.version>
        <unitils.version>3.1</unitils.version>
        <dbunit.version>2.4.8</dbunit.version>
    </properties>
    <modules>
        <module>chapter1</module>
    </modules>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

chapter1的pom文件配置依赖关系

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.smart</groupId>
        <artifactId>chapter</artifactId>
        <version>3.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>chapter1</artifactId>
    <version>3.1-SNAPSHOT</version>
    <name>第一章示例</name>
    <description>Spring 快速入门</description>
    <packaging>war</packaging>
    <dependencies>
        <!--① 依赖的Spring模块类库 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!--② 依赖的持久化类库-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!--③ 依赖的公共类库-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>${commons-dbcp.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectjweaver.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>com.springsource.org.apache.commons.logging</artifactId>
            <version>${apache.commons.version}</version>
        </dependency>
        <dependency>
            <groupId>fakepath</groupId>
            <artifactId>com.springsource.net.sf.cglib</artifactId>
            <version>2.1.3</version>
        </dependency>
        <!--④ 依赖的WEB类库-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>${jsp-api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>${standard.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${servlet-api.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <!--⑤ 依赖的测试类库-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>chapter1</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <!-- jetty插件 -->
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.5</version>
                <configuration>
                    <webAppSourceDirectory>src/main/webapp</webAppSourceDirectory>
                    <scanIntervalSeconds>3</scanIntervalSeconds>
                    <contextPath>/chapter1</contextPath>
                    <connectors>
                        <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                            <port>8088</port>
                        </connector>
                    </connectors>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

chapter项目的目录结构

wKiom1dblvSzENsTAABFydOLsqs491.png-wh_50

相对应的代码如下:

domain(领域对象)包代码如下:

package com.smart.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable {     private int userId;     private String userName;     private String password;     private String lastIp;     private Date lastVisit;     public String getLastIp() {         return lastIp;     }     public void setLastIp(String lastIp) {         this.lastIp = lastIp;     }     public Date getLastVisit() {         return lastVisit;     }     public void setLastVisit(Date lastVisit) {         this.lastVisit = lastVisit;     }     public int getUserId() {         return userId;     }     public void setUserId(int userId) {         this.userId = userId;     }     public String getUserName() {         return userName;     }     public void setUserName(String userName) {         this.userName = userName;     }     public String getPassword() {         return password;     }     public void setPassword(String password) {         this.password = password;     } } package com.smart.domain; import java.io.Serializable; import java.util.Date; public class LoginLog implements Serializable {     private int loginLogId;     private int userId;     private String ip;     private Date loginDate;     public String getIp() {         return ip;     }     public void setIp(String ip) {         this.ip = ip;     }     public Date getLoginDate() {         return loginDate;     }     public void setLoginDate(Date loginDate) {         this.loginDate = loginDate;     }     public int getLoginLogId() {         return loginLogId;     }     public void setLoginLogId(int loginLogId) {         this.loginLogId = loginLogId;     }     public int getUserId() {         return userId;     }     public void setUserId(int userId) {         this.userId = userId;     } }

dao(持久层)代码如下:

package com.smart.dao; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowCallbackHandler; import org.springframework.stereotype.Repository; import com.smart.domain.User; @Repository public class UserDao {     @Autowired     private JdbcTemplate jdbcTemplate;     public int getMatchCount(String userName, String password) {         String sqlStr = " SELECT count(*) FROM t_user "                 + " WHERE user_name =? and password=? ";         return jdbcTemplate.queryForInt(sqlStr, new Object[]{userName, password});     }     public User findUserByUserName(final String userName) {         String sqlStr = " SELECT user_id,user_name "                 + " FROM t_user WHERE user_name =? ";         final User user = new User();         jdbcTemplate.query(sqlStr, new Object[]{userName},                 new RowCallbackHandler() {                     public void processRow(ResultSet rs) throws SQLException {                         user.setUserId(rs.getInt("user_id"));                         user.setUserName(userName);                     }                 });         return user;     }     public void updateLoginInfo(User user) {         String sqlStr = " UPDATE t_user SET last_visit=?,last_ip=?"                 + " WHERE user_id =?";         jdbcTemplate.update(sqlStr, new Object[]{user.getLastVisit(),                 user.getLastIp(), user.getUserId()});     } } package com.smart.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import com.smart.domain.LoginLog; @Repository public class LoginLogDao {     @Autowired     private JdbcTemplate jdbcTemplate;     public void insertLoginLog(LoginLog loginLog) {         String sqlStr = "INSERT INTO t_login_log(user_id,ip,login_datetime) "                 + "VALUES(?,?,?)";         Object[] args = {loginLog.getUserId(), loginLog.getIp(),                 loginLog.getLoginDate()};         jdbcTemplate.update(sqlStr, args);     } }

在Spring中装配dao, 本案例在applicationContext.xml配置中装配dao

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
    <!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
    <context:component-scan base-package="com.smart.dao"/>
    <context:component-scan base-package="com.smart.service"/>
    
    <!-- 配置数据源 -->
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close" 
      p:driverClassName="com.mysql.jdbc.Driver"
      p:url="jdbc:mysql://localhost:3306/sampledb31"
      p:username="root"
      p:password="" />

   <!-- 配置Jdbc模板  -->
   <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
      p:dataSource-ref="dataSource" />
      
   <!-- 配置事务管理器 -->
   <bean id="transactionManager"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
      p:dataSource-ref="dataSource" />
      
   <!-- 通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
   <aop:config proxy-target-class="true">
      <aop:pointcut id="serviceMethod"
         expression=" execution(* com.smart.service..*(..))" />
      <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
   </aop:config>
   <tx:advice id="txAdvice" transaction-manager="transactionManager">
      <tx:attributes>
         <tx:method name="*" />
      </tx:attributes>
   </tx:advice>
</beans>

业务层(service)代码:

package com.smart.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.smart.dao.LoginLogDao; import com.smart.dao.UserDao; import com.smart.domain.LoginLog; import com.smart.domain.User; @Service public class UserService {     @Autowired     private UserDao userDao;     @Autowired     private LoginLogDao loginLogDao;     public boolean hasMatchUser(String userName, String password) {         int matchCount = userDao.getMatchCount(userName, password);         return matchCount > 0;     }     public User findUserByUserName(String userName) {         return userDao.findUserByUserName(userName);     }     public void loginSuccess(User user) {         LoginLog loginLog = new LoginLog();         loginLog.setUserId(user.getUserId());         loginLog.setIp(user.getLastIp());         loginLog.setLoginDate(user.getLastVisit());         loginLogDao.insertLoginLog(loginLog);     } }

在Spring中装配Service,具体内容将applicationContext.xml。

单元测试。TestNG是一种基于注解的新一代单元测试框架,通过添加灵活的配置、测试分类和参数设置以及依赖测试等特性来克服JUnit的不足之处。首先在pom.xml文件中配置testNG、Spring-test的两个类的依赖。详见chapter1项目下的pom.xml。

单元测试模块结构:

wKioL1dbnCmi-gL9AAAue8ffQck456.png-wh_50

单元测试代码如下:

package com.smart.service; import java.util.Date; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.*; import static org.testng.Assert.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import com.smart.domain.User; @ContextConfiguration(locations = {"/applicationContext.xml"}) public class UserServiceTest extends AbstractTestNGSpringContextTests {     @Autowired     private UserService userService;     @Test     public void hasMatchUser() {         boolean b1 = userService.hasMatchUser("admin", "123456");         boolean b2 = userService.hasMatchUser("admin", "1111");         assertTrue(b1);         assertTrue(!b2);     }     @Test     public void findUserByUserName() {         User user = userService.findUserByUserName("admin");         assertEquals(user.getUserName(), "admin");     }     @Test     public void loginSuccess() {         User user = userService.findUserByUserName("admin");         user.setUserId(1);         user.setUserName("admin");         user.setLastIp("192.168.12.7");         user.setLastVisit(new Date());         userService.loginSuccess(user);     } } package com.smart.dao; import com.smart.domain.User; import com.smart.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.Test; import java.util.Date; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @ContextConfiguration(locations = {"/applicationContext.xml"}) public class UserDaoTest extends AbstractTestNGSpringContextTests {     @Autowired     private UserDao userDao;     @Test     public void hasMatchUser() {         int count  = userDao.getMatchCount("admin", "123456");         assertTrue(count>0);     }     @Test     public void findUserByUserName() {         User user = userDao.findUserByUserName("admin");         assertNotNull(user);         assertEquals(user.getUserName(), "admin");     } } package com.smart.web; import com.smart.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; @ContextConfiguration(locations = {"classpath:applicationContext.xml","file:d:/actionSpring/chapter/chapter1/src/main/webapp/WEB-INF/viewspace-servlet.xml"}) public class LoginControllerTest extends AbstractTestNGSpringContextTests {     @Autowired     private AnnotationMethodHandlerAdapter handlerAdapter;     @Autowired     private LoginController controller;    //声明Request与Response模拟对象    private MockHttpServletRequest request;    private MockHttpServletResponse response;    //执行测试前先初始模拟对象    @BeforeMethod    public void before() {       request = new MockHttpServletRequest();       request.setCharacterEncoding("UTF-8");       response = new MockHttpServletResponse();         request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, true); //Spring3.1 存在的BUG    }    // 测试LoginController#loginCheck()方法    @Test    public void loginCheck() throws Exception {         //测试登陆成功的情况        request.setRequestURI("/admin/loginCheck.html");       request.addParameter("userName", "admin"); // 设置请求URL及参数       request.addParameter("password", "123456");       //向控制发起请求 ” /loginCheck.html”       ModelAndView mav = handlerAdapter.handle(request, response, controller);       User user = (User) request.getSession().getAttribute("user");       assertNotNull(mav);       assertEquals(mav.getViewName(), "main");       assertNotNull(user);         request.getSession().removeAttribute("user");         //测试登陆失败的情况         request.setRequestURI("/admin/loginCheck.html");         request.addParameter("userName", "test");         request.addParameter("password", "123456");         mav = handlerAdapter.handle(request, response, controller);         user = (User) request.getSession().getAttribute("user");         assertNotNull(mav);         assertEquals(mav.getViewName(), "login");         assertNull(user);    } }

示例更多内容及运行结果请见附件

本文出自 “阿酷博客源” 博客,请务必保留此出处http://aku28907.blog.51cto.com/5668513/1787920

转载于:https://my.oschina.net/mrku/blog/693727

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108968.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号