zoukankan      html  css  js  c++  java
  • 建立Spring工程及基本使用(实例)-IOC部分

    注:本文使用的IntelliJ IDEA版本为2019.3.3,Spring版本为5.0.2.RELEASE,操作系统为Win10。

    工程目录结构:

    各文件内容:

    - pox.xml

    <?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>org.example</groupId>
        <artifactId>Spring</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>  <!-- MySQL连接驱动 -->
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.18</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>javax.annotation</groupId>  <!-- Java中的注解 -->
                <artifactId>javax.annotation-api</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>commons-dbutils</groupId>  <!-- 持久层操作,QueryRunner支持 -->
                <artifactId>commons-dbutils</artifactId>
                <version>1.4</version>
            </dependency>
            <dependency>
                <groupId>c3p0</groupId>  <!-- 数据库连接池 -->
                <artifactId>c3p0</artifactId>
                <version>0.9.1.2</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>  <!-- Spring整合Junit -->
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
        </dependencies>
        <properties>
            <!-- 指定编译的JDK版本-->
            <maven.compiler.source>11</maven.compiler.source>
            <maven.compiler.target>11</maven.compiler.target>
            <!-- 指定编码格式 -->
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    </project>
    View Code

    基于XML的IOC配置

    Spring的配置文件

    bean标签:用于让 spring 来创建配置对象的。 默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。

    属性:

        id:给对象在容器中提供一个唯一标识。用于获取对象。

        class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。

        scope:指定对象的作用范围。

              * singleton: 单例的. 默认值.

              * prototype: 多例的.

              * request: WEB项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.

              * session: WEB项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.

              * global session: WEB项目中,Portle环境. 若无Portlet环境,则 globalSession 相当于 session.

        init-method:指定类中的初始化方法名称。

        destroy-method:指定类中销毁方法名称。

    生命周期:

        单例对象: scope="singleton"

            一个应用只有一个对象的实例。它的作用范围就是整个应用。

        生命周期:

            对象出生:当应用加载,创建容器时,对象就被创建了。

            对象活着:只要容器在,对象一直活着。

            对象死亡:当应用卸载,销毁容器时,对象就被销毁了。

    ​    多例对象: scope="prototype"

            每次访问对象时,都会重新创建对象实例。

        生命周期:

            对象出生:当使用对象时,创建新的对象实例。

            对象活着:只要对象在使用中,就一直活着。

            对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

    - bean.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:c="http://www.springframework.org/schema/c"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util.xsd
            ">
        <!-- Ioc: 控制反转,把对象的创建交给spring来管理 -->
    
        <!-- 配置accountDao -->
        <!-- bean标签实例化对象方式一:使用构造函数 -->
        <bean id="accountDao" class="dao.impl.AccountDaoImpl" >
            <property name="runner" ref="runner"/>
        </bean>
        <!-- bean标签实例化对象方式二:spring 管理静态工厂-使用静态工厂的方法创建对象
        <bean id="accountDao" class="factory.BeanFactory" factory-method="createAccountDaoImpl">
            <property name="runner" ref="runner"/>
        </bean>
        -->
        <!-- bean标签实例化对象方式三:spring 管理实例工厂-使用实例工厂的方法创建对象
        <bean id="beanFactory" class="factory.BeanFactory"/>
        <bean id="accountDao" factory-bean="beanFactory" factory-method="getAccountDaoImpl">
            <property name="runner" ref="runner"/>
        </bean>
        -->
        <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
            <constructor-arg name="ds" ref="dataSource"/>
        </bean>
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
            <property name="jdbcUrl" value="jdbc:mysql:///数据库?serverTimezone=Asia/Shanghai"/>
            <property name="user" value="用户名"/>
            <property name="password" value="密码"/>
        </bean>
    
    
        <!-- 配置accountService -->
        <!-- 依赖注入: 使用构造函数注入 -->
        <!--
        <bean id="accountService" class="service.impl.AccountServiceImpl">
            <constructor-arg name="accountDao" ref="accountDao"/>
        </bean>
        -->
        <!-- 依赖注入: 使用set方法注入 -->
        <bean id="accountService" class="service.impl.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"/>
        </bean>
        <!-- 依赖注入: 使用c名字空间注入, 本质是构造函数注入 -->
        <!-- 需添加 xmlns:c="http://www.springframework.org/schema/c" 约束
        <bean id="accountService" class="service.impl.AccountServiceImpl"
              c:accountDao-ref="accountDao"/>
        -->
        <!-- 依赖注入: 使用p名字空间注入, 本质是set方法注入 -->
        <!-- 需添加 xmlns:p="http://www.springframework.org/schema/p" 约束
        <bean id="accountService" class="service.impl.AccountServiceImpl"
              p:accountDao-ref="accountDao"/>
        -->

    <!-- 告知 spring 创建容器时要扫描的包,使用@Component等用于取代bean标签的注解时才需此项 --> <!-- <context:component-scan base-package="dao"/>--> <!-- <context:component-scan base-package="service"/>-->

    实体类(JavaBean)

    - Account.java

    public class Account implements Serializable {
        private Integer id;
        private Integer uid;
        private Double money;
    
        ...  // 省略Getter、Setter和toString方法
    }
    View Code

    持久层

    - IAccountDao.java

    public interface IAccountDao {
        List<Account> findAllAccount();
        int saveAccount(Account account);
        void updateAccount(Account account);
        void deleteAccountById(Integer id);
        Account findAccountById(Integer id);
    }
    View Code

    - AccountDaoImpl.java

    public class AccountDaoImpl implements IAccountDao {
        private QueryRunner runner;
    @Override
    public List<Account> findAllAccount() { try{ return runner.query("select * from account",new BeanListHandler<Account>(Account.class)); }catch (Exception e) { throw new RuntimeException(e); } } @Override public int saveAccount(Account account) { try { Connection conn = runner.getDataSource().getConnection(); // 获取连接对象 runner.update(conn,"insert account (uid,money) values (?,?)",account.getUid(),account.getMoney()); return runner.query(conn, "select last_insert_id()", rs -> rs.next()?rs.getInt(1):0); // 获得插入的id } catch (SQLException e) { throw new RuntimeException(e); } } @Override public void updateAccount(Account account) { try { runner.update("update account set uid=?,money=? where id=?",
                account.getUid(),account.getMoney(),account.getId()); }
    catch (SQLException e) { throw new RuntimeException(e); } } @Override public void deleteAccountById(Integer id) { try { runner.update("delete from account where id=?",id); } catch (SQLException e) { throw new RuntimeException(e); } } @Override public Account findAccountById(Integer id) { try { return runner.query("select * from account where id=?",new BeanHandler<>(Account.class),id); } catch (SQLException e) { throw new RuntimeException(e); } } public void setRunner(QueryRunner runner) { this.runner = runner; } }

    业务层

    - IAccountService.java

    public interface IAccountService {
        List<Account> findAllAccount();
        int saveAccount(Account account);
        void updateAccount(Account account);
        void deleteAccountById(Integer id);
        Account findAccountById(Integer id);
    }
    View Code

    - AccountServiceImpl.java

    public class AccountServiceImpl implements IAccountService {
        private IAccountDao accountDao;  // 持久层对象
    
        @Override
        public List<Account> findAllAccount(){
            return accountDao.findAllAccount();
        }
    
        @Override
        public int saveAccount(Account account) {
            return accountDao.saveAccount(account);
        }
    
        @Override
        public void updateAccount(Account account) {
            accountDao.updateAccount(account);
        }
    
        @Override
        public void deleteAccountById(Integer id) {
            accountDao.deleteAccountById(id);
        }
    
        @Override
        public Account findAccountById(Integer id) {
            return accountDao.findAccountById(id);
        }
    
        public AccountServiceImpl(){
            System.out.println("无参构造函数...");
        }
    
        public AccountServiceImpl(IAccountDao accountDao) {
            this.accountDao = accountDao;
            System.out.println("有参构造函数...");
        }
    
        public IAccountDao getAccountDao() {
            return accountDao;
        }
    
        public void setAccountDao(IAccountDao accountDao) {
            this.accountDao = accountDao;
        }
    }

    测试类

    - AccountServiceTest.java

    public class AccountServiceTest {
        private IAccountService as;
        private int curAccountId = 15;
    
        @Before
        public void init() {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            as  = (IAccountService) ac.getBean("accountService");
        }
    
        @Test
        public void testFindAllAccount() {
            List<Account> accounts = as.findAllAccount();
            for (Account account : accounts) {
                System.out.println(account);
            }
        }
    
        @Test
        public void testSaveAccount() {
            Account account = new Account();
            account.setUid(42);
            account.setMoney(1000d);
            curAccountId = as.saveAccount(account);
            System.out.println(curAccountId);
        }
    
        @Test
        public void testUpdateAccount() {
            Account account = as.findAccountById(curAccountId);
            account.setMoney(3000d);
            as.updateAccount(account);
        }
    
        @Test
        public void testDeleteAccountById() {
            as.deleteAccountById(curAccountId);
        }
    
        @Test
        public void testFindAccountById() {
            Account account = as.findAccountById(curAccountId);
            System.out.println(account);
        }
    }

    演示类

            注:演示类不是Sping项目中的结构,而是为了演示某些知识点所建的类

    演示XML文件中<bean>标签实例化对象的三种方式

    - BeanFactory.java

            注:XML文件配置请查看上文中的<!-- 配置accountDao -->部分

    /**
     * 用于演示bean标签实例化对象的三种方式
     */
    public class BeanFactory {
        // bean标签实例化对象方式一:使用构造函数
        public BeanFactory() {}
    
        // bean标签实例化对象方式二:spring 管理静态工厂-使用静态工厂的方法创建对象
        public static AccountDaoImpl createAccountDaoImpl() {
            return new AccountDaoImpl();
        }
    
        // bean标签实例化对象方式三:spring 管理实例工厂-使用实例工厂的方法创建对象
        public AccountDaoImpl getAccountDaoImpl() {
            return new AccountDaoImpl();
        }
    }
    演示基于XML的数组、集合等复杂结构的依赖注入

    - bean.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            ">
        <!-- 告知 spring 创建容器时要扫描的包 -->
        <context:component-scan base-package="domain"/>
    
        <bean id="demo" class="domain.Demo">
            <property name="name" value="张三"/>
            <property name="age" value="20"/>
            <property name="birthday" ref="now"/>
            <property name="pets">
                <array>
                    <value>汤姆猫</value>
                    <value>杰瑞鼠</value>
                </array>
            </property>
            <property name="friends">
                <list>
                    <value>王五</value>
                    <value>赵六</value>
                </list>
            </property>
            <property name="wives">
                <list>
                    <value>田甜</value>
                    <value>甄妮</value>
                </list>
            </property>
            <property name="contacts">
                <map>
                    <entry key="田甜" value="013"/>
                    <entry key="甄妮">
                        <value>017</value>
                    </entry>
                </map>
            </property>
            <property name="characters">
                <props>
                    <prop key="田甜">温柔</prop>
                    <prop key="甄妮">美丽</prop>
                </props>
            </property>
        </bean>
    
        <!-- 配置一个日期对象 -->
        <bean id="now" class="java.util.Date"/>
    </bean>

    - Demo.java

    /**
     * 用于演示依赖注入复杂结构(数组、List、Set、Map、Properties)
     */
    public class Demo implements Serializable {
        private String name;
        private Integer age;
        private Date birthday;
    
        private String[] pets;
    
        private List<String> friends;
    
        private Set<String> wives;
    
        private Map<String, String> contacts;
    
        private Properties characters;
    
        ...  // 省略Getter、Setter和toString方法
    }

    - DemoTest.java

    /**
     * ApplicationContext的三个常用实现类:
     *      ClassPathXmlApplicationContext:它可以加载类路径下的配置文件。要求配置文件必须在类路径下,否则无法加载。(常用)
     *      FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
     *      AnnotationConfigApplicationContext:当我们使用注解配置容器对象时,需要使用此类来创建spring容器,用来读取注解。
     *
     * 核心容器的两个接口引发出的问题:
     *  ApplicationContext:     单例对象适用
     *      创建核心容器对象时采取的策略是立即加载的方式。即只要一读取完配置文件就马上创建配置文件中配置的所有Bean对象。
     *  BeanFactory:            多例对象使用
     *      创建核心容器对象时采取的策略是延迟加载的方式。即什么时候需要Bean对象了,才会根据id去创建并获取对象。
     */
    public class DemoTest {
        public static void main(String[] args) {
            /* 使用ApplicationContext方式获取核心容器 */
            // 1.获取核心容器对象
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            // ApplicationContext ac = new FileSystemXmlApplicationContext("E:/Documents/IdeaProj/Spring/bean.xml");
    
            // 2.根据id获取Bean对象
            Demo demo = ac.getBean(Demo.class);  // 此方式自动转类型(根据class自动转)
            // Demo demo = (Demo) ac.getBean("demo");  // 此方式手动转类型
    
            System.out.println(demo);
    
    
            /* 使用BeanFactory方式获取核心容器 */
            /*
            Resource resource = new ClassPathResource("bean.xml");
            BeanFactory factory = new XmlBeanFactory(resource);
    
            Demo demo = ac.getBean(Demo.class);
             */
        }
    }

    基于注解的IOC配置

    取代Bean标签的注解:

    用于对象实例化

      @Component: 让 spring 来管理资源。相当于XML文件的 bean 标签。

      @Controller: 衍生注解, 与Component等价。一般用于表现层的注解。

      @Service: 衍生注解, 与Component等价。一般用于业务层的注解。

      @Repository: 衍生注解, 与Component等价。一般用于持久层的注解。

    用于注入数据

      @Autowired: 自动按照类型注入。当使用该注解时可省略set方法。若有多个类型相匹配时,可使用对象变量名作为 bean 的 id 在 Spring 容器查找,找到了也可注入成功。它只能注入其它 bean 类型。

      @Qualifier: 在自动按照类型注入的基础之上,再按照 bean 的 id 注入。它在给字段注入时必须与 Autowire 注解一起使用;但在给方法参数注入时,可以独立使用。

      @Resource: 直接按照 bean 的 id 注入。它也只能注入其它 bean 类型。(需要javax.annotation-api.jar支持)

      @Value: 注入基本数据类型和 String 类型的。以解决@Autowired、@Resource只能注入其它 bean 类型的问题。

    用于改变作用范围

      @Scope: 指定 bean 的作用范围。相当于XML文件 bean 标签中的 scope 属性。

            * 取值: singleton prototype request session globalsession

    用于设置生命周期

      @PostConstruct: 用于指定初始化方法。相当于XML文件 bean 标签中的 init-method 属性。

      @PreDestroy: 用于指定销毁方法。相当于XML文件 bean 标签中的 destroy-method 属性。

    使用XML和注解配置Bean的对比

     基于XML配置基于注解配置
    Bean定义 <bean id="..." class="..."/> @Componnent, 衍生类: @Repository @Service @Controller
    Bean名称 通过id或name指定 @Component("name")
    Bean注入 <constructor-arg> <property>或c p名字空间 @Autowried @Qualifier
    生命周期 init-method属性 destroy-method属性 @PostConstruct @PreDestroy
    作用范围 scope属性 @Scope
    适合场景 Bean来自第三方 Bean实现类由自己开发

    取代XML文件的注解:

      @Configuration: 用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。

    // 注:获取容器时使用: AnnotationApplicationContext(有@Configuration注解的类.class)
    // 例如:
    ApplicationContext ac = new AnnotationApplicationContext(SpringConfig.class);
    例子

      @ComponentScan: 用于指定 spring 在初始化容器时要扫描的包。相当于XML文件 context:component-scan 标签。

      @Bean: 该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。

      @PropertySource: 用于加载 .properties 文件中的配置。例如使用此注解指定连接数据库信息的 properties 配置文件的位置。

            * value[]: 用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath: 。

      @Import: 用于导入其它配置类。在引入其它配置类时,可以不用再写 @Configuration 注解。

    - SpringConfig.java
    /**
    * 定义Spring配置类
    */
    @Configuration
    @ComponentScan("com.example")
    @Import(JdbcConfig.class)
    public class SpringConfig {/*Spring配置类的内容*/}
    
    
    - JdbcConfig.java
    @Configuration
    @PropertySource("classpath:jdbc.properties")
    public class JdbcConfig {
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
        
        /**
        * 创建一个数据源,并存入 spring 容器中
        */
        @Bean(name="dataSource")
        public DataSource createDataSource() {
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    
    - jdbc.properties
    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql:///数据库?serverTimezone=Asia/Shanghai
    jdbc.username=用户名
    jdbc.password=密码
    例子

     初步改造:Bean实例化改为注解方式,但Spring配置依然使用xml配置

    - bean.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util.xsd
            ">
        <!-- 告知 spring 创建容器时要扫描的包 -->
        <context:component-scan base-package="domain"/>
    
        <!-- 配置一个日期对象 -->
        <bean id="now" class="java.util.Date"/>
    
        <util:list id="friends">
            <value>王五</value>
            <value>赵六</value>
        </util:list>
        <util:set id="wives">
            <value>田甜</value>
            <value>甄妮</value>
        </util:set>
        <util:map id="contacts">
            <entry key="田甜" value="013"/>
            <entry key="甄妮">
                <value>017</value>
            </entry>
        </util:map>
        <util:properties id="characters">
            <prop key="田甜">温柔</prop>
            <prop key="甄妮">美丽</prop>
        </util:properties>
    
    </beans>

    - Demo.java

    /**
     * 用于演示依赖注入复杂结构(数组、List、Set、Map、Properties)
     */
    @Component("demo")
    public class Demo implements Serializable {
        @Value("李四")
        private String name;
        @Value("21")
        private Integer age;
    
        @Autowired
        @Qualifier("now")
        private Date birthday;
    
        @Value("汤姆猫")
        private String[] pets;
    
        @Resource(name="friends")
        private List<String> friends;
    
        @Resource(name="wives")
        private Set<String> wives;
    
        @Resource(name="contacts")
        private Map<String, String> contacts;
    
        @Resource(name="characters")
        private Properties characters;
    
        ...  // 省略Getter、toString方法,采用注解方式无需Setter方法
    }

     注:DemoTest.java无更改,此时的Demo类的创建和依赖注入已不使用<bean>了。

    完全改造:Bean实例化和Spring配置均改为注解方式(即完全去除bean.xml)

    - AccountDaoImpl.java

    @Repository("accountDao")  // 增加Repository注解
    public class AccountDaoImpl implements IAccountDao {
        @Autowired  // 增加Autowired注解
        private QueryRunner runner;
        
        ... // 其余部分无改动  
    }

    - AccountServiceImpl.java

    @Service("accountService")  // 增加Service注解
    public class AccountServiceImpl implements IAccountService {
        @Autowired  // 增加Autowired注解
        private IAccountDao accountDao;
    
        ... // 其余部分无改动
    }

    注:IAccountDao.java和IAccountService.java均无改动。至此,<bean>的所有功能已完全被注解取代,接下来将建立Spring配置类利用注解完全取代bean.xml。

    - 新建 jdbc.properties,配置数据库连接信息。

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql:///数据库?serverTimezone=Asia/Shanghai
    jdbc.username=用户名
    jdbc.password=密码

    - 新建 JdbcConfig.java,以建立数据库连接。

    @Configuration  // 指定当前类是一个 spring 配置类
    @PropertySource("classpath:jdbc.properties")  // 引入jdbc.properties文件
    public class JdbcConfig {
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
    
        /**
         * 创建一个数据源,并存入 spring 容器中
         */
        @Bean(name="dataSource")  // 使用此方法创建一个对象,并且放入 spring 容器,相当于XML文件的 bean 标签
        public DataSource createDataSource() {
            try {
                ComboPooledDataSource ds = new ComboPooledDataSource();
                ds.setDriverClass(driver);
                ds.setJdbcUrl(url);
                ds.setUser(username);
                ds.setPassword(password);
                return ds;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        @Bean("runner")  // 创建QueryRunner,以便Spring注入
        @Scope("prototype")  // 使用多例对象,以免多个Dao同时执行时互相干扰。
        public QueryRunner createQueryRunner(DataSource ds) {
            return new QueryRunner(ds);
        }
    }

    - 新建 SpringConfig.java

    @Configuration  // 指定当前类是一个 spring 配置类
    @ComponentScan({"dao","service"})  // 告知Spring扫描的包,相当于XML文件 context:component-scan 标签
    @Import(JdbcConfig.class)  // 引入JdbcConfig类中的配置
    public class SpringConfig {
    
    }

    - AccountServiceTest.java

    public class AccountServiceTest {
        private IAccountService as;
        private int curAccountId = 19;
    
        @Before
        public void init() {
            ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);  // 改为注解获取的方式
            as  = (IAccountService) ac.getBean("accountService");
        }
    
        ... // 其余部分无改动
    }

    注:至此bean.xml(可删除)已被JdbcConfig类和SpringConfig类完全取缔,执行AccountServiceTest类中的测试方法,效果与使用基于XML配置时的执行效果相同。

    拓展:Spring整合Junit

    - AccountServiceTest.java

    @RunWith(SpringJUnit4ClassRunner.class)  // 需要spring-test.jar支持
    @ContextConfiguration(classes=SpringConfig.class)
    public class AccountServiceTest {
        @Autowired  // 增加Autowired注解
        private IAccountService as;
        private int curAccountId = 19;
    
        /* 此部分功能已由ContextConfiguration注解完成
        @Before
        public void init() {
            ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
            as  = (IAccountService) ac.getBean("accountService");
        }
        */
    
        ... // 其余部分无改动
    }
    View Code
  • 相关阅读:
    解析时间parse time
    php一些高级函数方法
    PHP定界符<<<EOF
    linux crontab(定时任务)
    svn提交按钮灰选
    centos官网下载地址
    centos7 yum安装LAMP
    saprfc
    RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密
    接入HTTPS协议的CAS登录配置
  • 原文地址:https://www.cnblogs.com/q10040/p/13046704.html
Copyright © 2011-2022 走看看