注解实现Spring的IOC

本文介绍如何通过自定义@Service、@Autowired等注解来实现基于注解的IOC容器,支持Bean对象创建及依赖注入,并结合转账案例展示了声明式事务控制的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

要求

自定义@Service、@Autowired、@Transactional注解类,完成基于注解的IOC容器(Bean对象创建及依赖注入维护)和声明式事务控制,写到转账工程中,并且可以实现转账成功和转账异常时事务回滚

注意考虑以下情况:

1)注解有无value属性值【@service(value="") @Repository(value="")】

2)service层是否实现接口的情况【jdk还是cglib】

实现

1. 依赖配置

 <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>


  <dependencies>
    <!-- 单元测试Junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <!-- mysql数据库驱动包 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.35</version>
    </dependency>
    <!--druid连接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.21</version>
    </dependency>

    <!-- servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- jackson依赖 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.6</version>
    </dependency>

    <!--dom4j依赖-->
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <!--xpath表达式依赖-->
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.1.6</version>
    </dependency>
    <!--引入cglib依赖包-->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>2.1_2</version>
    </dependency>
    <dependency>
      <groupId>org.reflections</groupId>
      <artifactId>reflections</artifactId>
      <version>0.9.11</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!-- 配置Maven的JDK编译级别 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.2</version>
        <configuration>
          <source>11</source>
          <target>11</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>

      <!-- tomcat7插件 -->
      <!-- 注意:目前来说,maven中央仓库还没有tomcat8的插件 -->
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>8080</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

2. 自定义注解

/**
 * 自定义注解@Autowired
 * @author lane
 * @date 2021年03月28日 下午6:37
 */
@Target(ElementType.FIELD) //作用于字段
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
    boolean required() default true;
}

/**
 * 自定义注解@Componet
 * @author lane
 * @date 2021年03月28日 下午6:37
 */
@Target(ElementType.TYPE) //用于描述类、接口(包括注解类型) 或enum声明
@Retention(RetentionPolicy.RUNTIME) //运行时有效
public @interface Componet {
    String value() default "";
}

/**
 * 自定义注解@Repository
 * @author lane
 * @date 2021年03月28日 下午6:37
 */
@Target(ElementType.TYPE) //用于描述类、接口(包括注解类型) 或enum声明
@Retention(RetentionPolicy.RUNTIME) //运行时有效
public @interface Repository {
    String value() default "";
}

/**
 * 自定义注解@Service
 * @author lane
 * @date 2021年03月28日 下午6:37
 */
@Target(ElementType.TYPE) //用于描述类、接口(包括注解类型) 或enum声明
@Retention(RetentionPolicy.RUNTIME) //运行时有效
public @interface Service {
    String value() default "";
}

/**
 * 自定义注解@Transactional
 * @author lane
 * @date 2021年03月28日 下午6:37
 */

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional {
    String value() default "TransactionManager";

}

3. 数据库连接工具类

3.1 连接池DruidUtils
package com.lagou.edu.utils;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * @author  
 */
public class DruidUtils {

    private DruidUtils(){
    }

    private static DruidDataSource druidDataSource = new DruidDataSource();


    static {
        druidDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/bank");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root");

    }

    public static DruidDataSource getInstance() {
        return druidDataSource;
    }

}

3.2 连接ConnectionUtils
package com.lagou.edu.utils;

import com.lagou.edu.annotation.Service;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * @author  
 */
@Service
public class ConnectionUtils {

    /*private ConnectionUtils() {

    }

    private static ConnectionUtils connectionUtils = new ConnectionUtils();

    public static ConnectionUtils getInstance() {
        return connectionUtils;
    }*/


    private ThreadLocal<Connection> threadLocal = new ThreadLocal<>(); // 存储当前线程的连接

    /**
     * 从当前线程获取连接
     */
    public Connection getCurrentThreadConn() throws SQLException {
        /**
         * 判断当前线程中是否已经绑定连接,如果没有绑定,需要从连接池获取一个连接绑定到当前线程
          */
        Connection connection = threadLocal.get();
        if(connection == null) {
            // 从连接池拿连接并绑定到线程
            connection = DruidUtils.getInstance().getConnection();
            // 绑定到当前线程
            threadLocal.set(connection);
        }
        return connection;

    }
}
3.3 事务管理器TransactionManager
package com.lagou.edu.utils;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;

import java.sql.SQLException;

/**
 * @author  
 *
 * 事务管理器类:负责手动事务的开启、提交、回滚
 */
@Service
public class TransactionManager {
    @Autowired
    private ConnectionUtils connectionUtils;

    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }

    /*private TransactionManager(){

    }

    private static TransactionManager transactionManager = new TransactionManager();

    public static TransactionManager getInstance() {
        return  transactionManager;
    }*/



    // 开启手动事务控制
    public void beginTransaction() throws SQLException {
        connectionUtils.getCurrentThreadConn().setAutoCommit(false);
    }


    // 提交事务
    public void commit() throws SQLException {
        connectionUtils.getCurrentThreadConn().commit();
    }


    // 回滚事务
    public void rollback() throws SQLException {
        connectionUtils.getCurrentThreadConn().rollback();
    }
}

3.4 JSON转换工具类
package com.lagou.edu.utils;

import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * JSON工具类(使用的是jackson实现的)
 * @author  
 */
public class JsonUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     * @param data
     * @return
     */
    public static String object2Json(Object data) {
    	try {
			String string = MAPPER.writeValueAsString(data);
			return string;
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
    	return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param beanType 对象中的object类型
     * @return
     */
    public static <T> T json2Pojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
        	e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     * @param jsonData
     * @param beanType
     * @return
     */
    public static <T>List<T> json2List(String jsonData, Class<T> beanType) {
    	JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
    	try {
    		List<T> list = MAPPER.readValue(jsonData, javaType);
    		return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
    	
    	return null;
    }
    
}

4. Pojo类

package com.lagou.edu.pojo;

/**
 * @author  
 */
public class Account {

    private String cardNo;
    private String name;
    private int money;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public String getCardNo() { return cardNo; }

    public void setCardNo(String cardNo) { this.cardNo = cardNo;}

    @Override
    public String toString() {
        return "Account{" +
                "cardNo='" + cardNo + '\'' +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

package com.lagou.edu.pojo;

/**
 * @author  
 */
public class Result {

    private String status;
    private String message;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "Result{" +
                "status='" + status + '\'' +
                ", message='" + message + '\'' +
                '}';
    }
}

5. 持久层Dao

5.1 接口

/**
 * @author  
 */
public interface AccountDao {

    Account queryAccountByCardNo(String cardNo) throws Exception;

    int updateAccountByCardNo(Account account) throws Exception;
}

5.2 实现类
package com.lagou.edu.dao.impl;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Repository;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.pojo.Account;
import com.lagou.edu.dao.AccountDao;
import com.lagou.edu.utils.ConnectionUtils;
import com.lagou.edu.utils.DruidUtils;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * @author  
 */
@Service("AccountDao")
@Repository("AccountDao")
public class JdbcAccountDaoImpl implements AccountDao {
    @Autowired
    private ConnectionUtils connectionUtils;

    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }


    public void init() {
        System.out.println("初始化方法.....");
    }

    public void destory() {
        System.out.println("销毁方法......");
    }

    @Override
    public Account queryAccountByCardNo(String cardNo) throws Exception {
        //从连接池获取连接
        // Connection con = DruidUtils.getInstance().getConnection();
        Connection con = connectionUtils.getCurrentThreadConn();
        String sql = "select * from account where cardNo=?";
        PreparedStatement preparedStatement = con.prepareStatement(sql);
        preparedStatement.setString(1,cardNo);
        ResultSet resultSet = preparedStatement.executeQuery();

        Account account = new Account();
        while(resultSet.next()) {
            account.setCardNo(resultSet.getString("cardNo"));
            account.setName(resultSet.getString("name"));
            account.setMoney(resultSet.getInt("money"));
        }

        resultSet.close();
        preparedStatement.close();
        //con.close();

        return account;
    }

    @Override
    public int updateAccountByCardNo(Account account) throws Exception {

        // 从连接池获取连接
        // 改造为:从当前线程当中获取绑定的connection连接
        //Connection con = DruidUtils.getInstance().getConnection();
        Connection con = connectionUtils.getCurrentThreadConn();
        String sql = "update account set money=? where cardNo=?";
        PreparedStatement preparedStatement = con.prepareStatement(sql);
        preparedStatement.setInt(1,account.getMoney());
        preparedStatement.setString(2,account.getCardNo());
        int i = preparedStatement.executeUpdate();

        preparedStatement.close();
        //con.close();
        return i;
    }
}

6. 业务层service

6.1 接口
public interface TransferService {
    public void setAccountDao(AccountDao accountDao);
    void transfer(String fromCardNo,String toCardNo,int money) throws Exception;
}
6.2 实现类
package com.lagou.edu.service.impl;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.annotation.Transactional;
import com.lagou.edu.dao.AccountDao;
import com.lagou.edu.pojo.Account;
import com.lagou.edu.service.TransferService;
import com.lagou.edu.utils.ConnectionUtils;
import com.lagou.edu.utils.TransactionManager;

/**
 * @author
 */
@Service("TransferService")
@Transactional
public class TransferServiceImpl implements TransferService {

    //private AccountDao accountDao = new JdbcAccountDaoImpl();

    // private AccountDao accountDao = (AccountDao) BeanFactory.getBean("accountDao");

    // 最佳状态
    @Autowired
    private AccountDao accountDao;

    // 构造函数传值/set方法传值

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }



    @Override
    public void transfer(String fromCardNo, String toCardNo, int money) throws Exception {

        /*try{
            // 开启事务(关闭事务的自动提交)
            TransactionManager.getInstance().beginTransaction();*/

            Account from = accountDao.queryAccountByCardNo(fromCardNo);
            Account to = accountDao.queryAccountByCardNo(toCardNo);

            from.setMoney(from.getMoney()-money);
            to.setMoney(to.getMoney()+money);

            accountDao.updateAccountByCardNo(to);
            int c = 1/0;
            accountDao.updateAccountByCardNo(from);

        /*    // 提交事务

            TransactionManager.getInstance().commit();
        }catch (Exception e) {
            e.printStackTrace();
            // 回滚事务
            TransactionManager.getInstance().rollback();

            // 抛出异常便于上层servlet捕获
            throw e;

        }*/




    }
}

7. 核心工厂类

7.1 动态代理工厂类
package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.pojo.Account;
import com.lagou.edu.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author  
 *
 *
 * 代理对象工厂:生成代理对象的
 */
@Service
public class ProxyFactory {

    @Autowired
    private TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

//
//
//    private static ProxyFactory proxyFactory = new ProxyFactory();
//
//    public static ProxyFactory getInstance() {
//        return proxyFactory;
//    }


    /**
     * Jdk动态代理
     * @param obj  委托对象
     * @return   代理对象
     */
    public Object getJdkProxy(Object obj) {

        // 获取代理对象
        return  Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object result = null;

                        try{
                            // 开启事务(关闭事务的自动提交)
                            transactionManager.beginTransaction();

                            result = method.invoke(obj,args);

                            // 提交事务

                            transactionManager.commit();
                        }catch (Exception e) {
                            e.printStackTrace();
                            // 回滚事务
                            transactionManager.rollback();

                            // 抛出异常便于上层servlet捕获
                            throw e;

                        }

                        return result;
                    }
                });

    }


    /**
     * 使用cglib动态代理生成代理对象
     * @param obj 委托对象
     * @return
     */
    public Object getCglibProxy(Object obj) {
        return  Enhancer.create(obj.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object result = null;
                try{
                    // 开启事务(关闭事务的自动提交)
                    transactionManager.beginTransaction();
                    System.out.println("开启事务");
                    result = method.invoke(obj,objects);

                    // 提交事务
                    System.out.println("提交事务");
                    transactionManager.commit();
                }catch (Exception e) {
                    e.printStackTrace();
                    // 回滚事务
                    transactionManager.rollback();
                    System.out.println("回滚事务");
                    // 抛出异常便于上层servlet捕获
                    throw e;

                }
                return result;
            }
        });
    }
}

7.2 核心注解解析工厂类
package com.lagou.edu.factory;
import com.alibaba.druid.util.StringUtils;
import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;

import com.lagou.edu.annotation.Transactional;
import com.lagou.edu.dao.AccountDao;
import com.lagou.edu.service.TransferService;
import org.reflections.Reflections;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 工厂类,生产对象(使用注解反射技术)
 * @author lane
 * @date 2021年03月28日 下午6:59
 */
public class BeanFactoryAnnotation {

    /**
     * 任务一:读取解析anno,通过反射技术实例化对象并且存储待用(map集合)
     * 任务二:对外提供获取实例对象的接口(根据id获取)
     */
    //仿照xml ioc思想存储对象的集合
    private static Map<String,Object> map = new HashMap<>();
    //解析anno,生成对象存入map当中
    static{

        try{
            //反射扫描包下所有的对象
            Reflections reflections = new Reflections("com.lagou.edu");
            //获取所有的注解class对象
            Set<Class<?>> clazzs = reflections.getTypesAnnotatedWith(Service.class);
            //遍历生成每一个对象
            for (Class clazz:clazzs ) {
                Object obj = clazz.newInstance();
                Service service = (Service) clazz.getAnnotation(Service.class);
                //判断是否在注解上加上自己的value值
                if (StringUtils.isEmpty(service.value())){
                    String[] className = clazz.getName().split("\\.");
                    map.put(className[className.length-1],obj);
                }else{
                    //使用自己定义的ID值
                    map.put(service.value(),obj);
                }
            }
            // 实例化完成之后维护对象的依赖关系,检查哪些对象需要传值进入,根据它的配置Autowired注解,我们传入相应的值
            for (Map.Entry<String,Object> entry:map.entrySet()) {
                Object object = entry.getValue();
                Class clazz = object.getClass();
                //获取每一个属性
                Field[] declaredFields = clazz.getDeclaredFields();
                //遍历每一个属性,判断是否有Autowired注解
                for (Field field:declaredFields) {
                    //判断是否使用注解
                    if(field.isAnnotationPresent(Autowired.class) &&field.getAnnotation(Autowired.class).required()){
                        //获取要注入的类
                        String[] fieldNames = field.getType().getName().split("\\.");
                        String fieldName = fieldNames[fieldNames.length-1];
                        Method[] methods = clazz.getMethods();
                        //遍历查找该属性是否有set方法,若有则调用注入该属性对象
                        for (Method method:methods) {
                            if (method.getName().equalsIgnoreCase("set"+fieldName)){
                                Object o = map.get(fieldName);
                                System.out.println(o.toString());

                                method.invoke(object,o);

                            }
                        }


                    }
                }

                //判断该类是否有@Transactional注解,有则用代理对象替换掉原来的对象
                if (clazz.isAnnotationPresent(Transactional.class)){
                    ProxyFactory proxyFactory = (ProxyFactory)map.get("ProxyFactory");
                    Class[] interfaces = clazz.getInterfaces();
                    if(interfaces!=null&interfaces.length>0){
                        //jdk动态代理
                        object = proxyFactory.getJdkProxy(object);
                    }else {
                        //cglib动态代理
                        object = proxyFactory.getCglibProxy(object);
                    }

                }
                //注入,代理之后对象重新存放入map内
                map.put(entry.getKey(),object);
            }


        }catch (Exception e){

            e.printStackTrace();
        }

    }
    //对外提供根据名称获取bean对象方法
    public static Object getBeanAnno(String beanName){
        return map.get(beanName);
    }

}

8 测试用servlet

package com.lagou.edu.servlet;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.factory.BeanFactory;
import com.lagou.edu.factory.BeanFactoryAnnotation;
import com.lagou.edu.factory.ProxyFactory;
import com.lagou.edu.service.impl.TransferServiceImpl;
import com.lagou.edu.utils.JsonUtils;
import com.lagou.edu.pojo.Result;
import com.lagou.edu.service.TransferService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 
 */
@WebServlet(name="transferServlet",urlPatterns = "/transferServlet")
public class TransferServlet extends HttpServlet {

    // 1. 实例化service层对象
    //private TransferService transferService = new TransferServiceImpl();
    //private TransferService transferService = (TransferService) BeanFactory.getBean("transferService");

    // 从工厂获取委托对象(委托对象是增强了事务控制的功能)

    // 首先从BeanFactory获取到proxyFactory代理工厂的实例化对象
    //public ProxyFactory proxyFactory = (ProxyFactory) BeanFactory.getBean("proxyFactory");
    // public TransferService transferService = (TransferService) proxyFactory.getJdkProxy(BeanFactory.getBean("transferService")) ;

    //使用工厂方法获取对象
    public TransferService transferService = (TransferService)BeanFactoryAnnotation.getBeanAnno("TransferService");
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);



    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置请求体的字符编码
        req.setCharacterEncoding("UTF-8");

        String fromCardNo = req.getParameter("fromCardNo");
        String toCardNo = req.getParameter("toCardNo");
        String moneyStr = req.getParameter("money");
        int money = Integer.parseInt(moneyStr);

        Result result = new Result();

        try {

            // 2. 调用service层方法
            transferService.transfer(fromCardNo,toCardNo,money);
            result.setStatus("200");
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus("201");
            result.setMessage(e.toString());
        }

        // 响应
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().print(JsonUtils.object2Json(result));
    }
}

前端html
<!doctype html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>转账汇款</title>

    <script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>


    <style type="text/css">
        body {
            background-color:#00b38a;
            text-align:center;
        }

        .lp-login {
            position:absolute;
            width:500px;
            height:300px;
            top:50%;
            left:50%;
            margin-top:-250px;
            margin-left:-250px;
            background: #fff;
            border-radius: 4px;
            box-shadow: 0 0 10px #12a591;
            padding: 57px 50px 35px;
            box-sizing: border-box
        }


        .lp-login .submitBtn {
            display:block;
            text-decoration:none;
            height: 48px;
            width: 150px;
            line-height: 48px;
            font-size: 16px;
            color: #fff;
            text-align: center;
            background-image: -webkit-gradient(linear, left top, right top, from(#09cb9d), to(#02b389));
            background-image: linear-gradient(90deg, #09cb9d, #02b389);
            border-radius: 3px
        }


        input[type='text'] {
            height:30px;
            width:250px;
        }

        span {
            font-style: normal;
            font-variant-ligatures: normal;
            font-variant-caps: normal;
            font-variant-numeric: normal;
            font-variant-east-asian: normal;
            font-weight: normal;
            font-stretch: normal;
            font-size: 14px;
            line-height: 22px;
            font-family: "Hiragino Sans GB", "Microsoft Yahei", SimSun, Arial, "Helvetica Neue", Helvetica;
        }

    </style>
    <script type="text/javascript">
        $(function(){
            $(".submitBtn").bind("click",function(){
                var fromAccount = $("#fromAccount").val();
                var toAccount = $("#toAccount").val();
                var money = $("#money").val();

                if(money == null || $.trim(money).length == 0){
                    alert("sorry,必须输入转账金额~");
                    return;
                }

                $.ajax({
                    url:'/transferServlet',
                    type:'POST',    //GET
                    async:false,    //或false,是否异步
                    data:{
                        fromCardNo:fromAccount.split(' ')[1],
                        toCardNo:toAccount.split(' ')[1],
                        money:money
                    },
                    timeout:5000,    //超时时间
                    dataType:'json', //返回的数据格式:json/xml/html/script/jsonp/text
                    success:function(data){
                        if("200" == data.status){
                            alert("转账成功~~~");
                        }else{
                            alert("转账失败~~~,message:" + data.message);
                        }
                    }
                })
            })
        })

        //检查输入值是否为整数
        function checkFormat(obj){
            var reg = /^[0-9]+[0-9]*]*$/;
            if($.trim($(obj).val()).length>0){
                if(!reg.test($(obj).val())){
                    alert("输入格式错误!请输整数!");
                    $(obj).val("");
                }else{
                    $(obj).val(parseInt($(obj).val()));
                }
            }
        }
    </script>
</head>
<body>


<form>
    <table class="lp-login">
        <tr>
            <td align="right"><span>收款账户</span></td>
            <td align="center">
                <input type="text" id="toAccount" value="韩梅梅 6029621011001" disabled></input>
            </td>
        </tr>
        <tr>
            <td align="right"><span>付款账户</span></td>
            <td align="center">
                <input type="text" id="fromAccount" value="李大雷 6029621011000" disabled></input>
            </td>
        </tr>
        <tr>
            <td align="right"><span>转账金额</span></td>
            <td align="center">
                <input type="text" id="money" onblur="checkFormat(this)"></input>
            </td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <a href="javasrcipt:void(0)" class="submitBtn"><span>转 出</span></a>
            </td>
        </tr>
    </table>
</form>

</body>
</html>

总结

注解实现IOC是在手写实现Spring的IOC基础上改编而成,有大量的代码被注释掉了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值