10 Spring框架--基于注解和xml的配置的应用案例
1.项目结构
2.基于xml配置的项目
<1>账户的业务层接口及其实现类
IAccountService.java
package lucky.service; import lucky.domain.Account; import java.util.List; /** * 账户的业务层接口 */ public interface IAccountService { /** * 查询所有 * @return */ List<Account> queryAllAccount(); /** * 查询一个 * @return */ Account queryAccountById(Integer accountId); /** * 保存账户 * @param account */ void saveAccount(Account account); /** * 更新账户信息 * @param account */ void updateAccount(Account account); /** * 删除用户 * @param accountId */ void deleteAccount(Integer accountId); }
AccountServiceImpl.java
package lucky.service.impl; import lucky.dao.IAccountDao; import lucky.domain.Account; import lucky.service.IAccountService; import java.util.List; public class AccountServiceImpl implements IAccountService { private IAccountDao accountDao; public void setAccountDao(IAccountDao accountDao) { this.accountDao = accountDao; } public List<Account> queryAllAccount() { return accountDao.queryAllAccount(); } public Account queryAccountById(Integer accountId) { return accountDao.queryAccountById(accountId); } public void saveAccount(Account account) { accountDao.saveAccount(account); } public void updateAccount(Account account) { accountDao.updateAccount(account); } public void deleteAccount(Integer accountId) { accountDao.deleteAccount(accountId); } }
<2>账户的持久层接口及其实现类
IAccountDao.java
package lucky.dao; import lucky.domain.Account; import java.util.List; /** * 账户的持久层接口 */ public interface IAccountDao { /** * 查询所有 * @return */ List<Account> queryAllAccount(); /** * 查询一个 * @return */ Account queryAccountById(Integer accountId); /** * 保存账户 * @param account */ void saveAccount(Account account); /** * 更新账户信息 * @param account */ void updateAccount(Account account); /** * 删除用户 * @param accountId */ void deleteAccount(Integer accountId); }
IAccountDaoImpl.java
package lucky.dao.impl; import lucky.dao.IAccountDao; import lucky.domain.Account; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import java.sql.SQLException; import java.util.List; /** * 账户的持久层实现类 */ public class IAccountDaoImpl implements IAccountDao { private QueryRunner runner; public void setRunner(QueryRunner runner) { this.runner = runner; } public List<Account> queryAllAccount() { try { return runner.query("select * from account",new BeanListHandler<Account>(Account.class)); } catch (SQLException e) { throw new RuntimeException(e); } } public Account queryAccountById(Integer accountId) { try { return runner.query("select * from account where id=?",new BeanHandler<Account>(Account.class),accountId); } catch (SQLException e) { throw new RuntimeException(e); } } public void saveAccount(Account account) { try { runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney()); } catch (SQLException e) { throw new RuntimeException(e); } } public void updateAccount(Account account) { try { runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId()); } catch (SQLException e) { throw new RuntimeException(e); } } public void deleteAccount(Integer accountId) { try { runner.update("delete from account where id=?",accountId); } catch (SQLException e) { throw new RuntimeException(e); } } }
<3>数据库表account对应的Account.java
package lucky.domain; import java.io.Serializable; public class Account implements Serializable { private Integer id; private String name; private Float money; 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 Float getMoney() { return money; } public void setMoney(Float money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } }
<4>bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <!-- 配置Service --> <!--创建AccountServiceImpl这个类的bean对象--> <bean id="accountService" class="lucky.service.impl.AccountServiceImpl"> <!-- 使用set方法,注入dao --> <property name="accountDao" ref="accountDao"></property> </bean> <!--配置Dao对象--> <bean id="accountDao" class="lucky.dao.impl.IAccountDaoImpl"> <!-- 使用set方法,注入QueryRunner --> <property name="runner" ref="runner"></property> </bean> <!--配置QueryRunner--> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <!--使用构造函数注入,注入数据源--> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!--连接数据库的必备信息--> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property> <property name="user" value="root"></property> <property name="password" value="plj824"></property> </bean> </beans>
<5>测试类
import lucky.domain.Account; import lucky.service.IAccountService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class AccountServiceTest { @Test public void testQueryAllAccount(){ //1.获取容器 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as= (IAccountService) ac.getBean("accountService"); //3.执行方法 List<Account> accounts = as.queryAllAccount(); for (Account account : accounts) { System.out.println(account); } } @Test public void testQueryAccountById(){ //1.获取容器 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as= (IAccountService) ac.getBean("accountService"); //3.执行方法 Account account1 = as.queryAccountById(1); System.out.println(account1); } @Test public void testSaveAccount(){ //1.获取容器 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as= (IAccountService) ac.getBean("accountService"); //3.执行方法 Account account=new Account(); account.setName("lucky"); account.setMoney(1000f); as.saveAccount(account); } @Test public void testUpdateAccount(){ //1.获取容器 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as= (IAccountService) ac.getBean("accountService"); //3.执行方法 Account account1 = as.queryAccountById(1); account1.setMoney(2000f); as.updateAccount(account1); } @Test public void testDeleteAccount(){ //1.获取容器 ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml"); //2.得到业务层对象 IAccountService as= (IAccountService) ac.getBean("accountService"); //3.执行方法 as.deleteAccount(4); } }
效果图:
数据库表:
testQueryAllAccount()测试输出:
testQueryAccountById()
2.基于部分注解配置的项目(一定程度上还是要使用xml配置,自己写的类用注解,jar包的类用xml配置)
<1>修改IAccountDaoImpl.java
package lucky.dao.impl; import lucky.dao.IAccountDao; import lucky.domain.Account; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.sql.SQLException; import java.util.List; /** * 账户的持久层实现类 */ @Repository("accountDao") public class IAccountDaoImpl implements IAccountDao { @Autowired private QueryRunner runner; public List<Account> queryAllAccount() { try { return runner.query("select * from account",new BeanListHandler<Account>(Account.class)); } catch (SQLException e) { throw new RuntimeException(e); } } public Account queryAccountById(Integer accountId) { try { return runner.query("select * from account where id=?",new BeanHandler<Account>(Account.class),accountId); } catch (SQLException e) { throw new RuntimeException(e); } } public void saveAccount(Account account) { try { runner.update("insert into account(name,money)values(?,?)",account.getName(),account.getMoney()); } catch (SQLException e) { throw new RuntimeException(e); } } public void updateAccount(Account account) { try { runner.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId()); } catch (SQLException e) { throw new RuntimeException(e); } } public void deleteAccount(Integer accountId) { try { runner.update("delete from account where id=?",accountId); } catch (SQLException e) { throw new RuntimeException(e); } } }
<2>AccountServiceImpl.java
package lucky.service.impl; import lucky.dao.IAccountDao; import lucky.domain.Account; import lucky.service.IAccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service("accountService") public class AccountServiceImpl implements IAccountService { @Autowired private IAccountDao accountDao; public List<Account> queryAllAccount() { return accountDao.queryAllAccount(); } public Account queryAccountById(Integer accountId) { return accountDao.queryAccountById(accountId); } public void saveAccount(Account account) { accountDao.saveAccount(account); } public void updateAccount(Account account) { accountDao.updateAccount(account); } public void deleteAccount(Integer accountId) { accountDao.deleteAccount(accountId); } }
<3>修改bean.xml
<?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:context="http://www.springframework.org/schema/context" 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="lucky"></context:component-scan> <!--配置QueryRunner--> <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype"> <!--使用构造函数注入,注入数据源--> <constructor-arg name="ds" ref="dataSource"></constructor-arg> </bean> <!-- 配置数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!--连接数据库的必备信息--> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property> <property name="user" value="root"></property> <property name="password" value="plj824"></property> </bean> </beans>
3.基于纯注解配置的项目
spring中的新注解
@Configuration
作用:指定当前类是一个配置类
细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。
@ ComponentScan
作用:用于通过注解指定spring在创建容器时要扫描的包
属性:
value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。
我们使用此注解就等同于在xml中配置了:
<context:component-scan base-package="lucky"></context:component-scan>
@ Bean
作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中
属性:
name:用于指定bean的id。当不写时,默认值是当前方法的名称
细节:
当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。
查找的方式和Autowired注解的作用是一样的
@ Import
作用:用于导入其他的配置类
属性:
value:用于指定其他配置类的字节码。
当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类
@ PropertySource
作用:用于指定properties文件的位置
属性:
value:指定文件的名称和路径。
关键字:classpath,表示类路径下
<1>项目结构
<2>在java包下创建名为config的包
SpringConfiguration.java为主配置类
package config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; /** * 该类是一个配置类,它的作用和bean.xml是一样的 * spring中的新注解 * Configuration * 作用:指定当前类是一个配置类 * 细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写。 * ComponentScan * 作用:用于通过注解指定spring在创建容器时要扫描的包 * 属性: * value:它和basePackages的作用是一样的,都是用于指定创建容器时要扫描的包。 * 我们使用此注解就等同于在xml中配置了: * <context:component-scan base-package="lucky"></context:component-scan> * Bean * 作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中 * 属性: * name:用于指定bean的id。当不写时,默认值是当前方法的名称 * 细节: * 当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找有没有可用的bean对象。 * 查找的方式和Autowired注解的作用是一样的 * Import * 作用:用于导入其他的配置类 * 属性: * value:用于指定其他配置类的字节码。 * 当我们使用Import的注解之后,有Import注解的类就父配置类,而导入的都是子配置类 * PropertySource * 作用:用于指定properties文件的位置 * 属性: * value:指定文件的名称和路径。 * 关键字:classpath,表示类路径下 */ @Configuration @ComponentScan(basePackages = "lucky") @PropertySource("classpath:jdbcConfig.properties") @Import(JdbcConfig.class) public class SpringConfiguration { }
JdbcConfig.java
package config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.apache.commons.dbutils.QueryRunner; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Scope; import javax.sql.DataSource; /** * 和spring连接数据库相关的配置类 */ 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; /** * 用于创建一个QueryRunner对象 * @param dataSource * @return */ @Bean(name="runner") @Scope("prototype") public QueryRunner createQueryRunner(@Qualifier("ds2") DataSource dataSource){ return new QueryRunner(dataSource); } /** * 创建数据源对象 * @return */ @Bean(name="ds2") 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(name="ds1") public DataSource createDataSource1(){ try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setDriverClass(driver); ds.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis"); ds.setUser(username); ds.setPassword(password); return ds; }catch (Exception e){ throw new RuntimeException(e); } } }
jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring jdbc.username=root jdbc.password=plj824
此时,没有bean.xml文件了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)