我爱Java系列---【Spring基于全注解的 IOC 配置】
总结:
1. @Configuration:
作用:用于指定当前类是一个 spring 配置类,当创建容器时会从该类上加载注解。获取容器时需要使用
AnnotationApplicationContext(有@Configuration 注解的类.class)。
属性:
value:用于指定配置类的字节码
示例代码: /** * spring 的配置类,相当于 bean.xml 文件 * @Version 1.0 */ @Configuration public class SpringConfiguration { } 注意: 我们已经把配置文件用类来代替了,但是如何配置创建容器时要扫描的包呢? 请看下一个注解。
2. @ComponentScan
作用:
用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/>是一样的。
属性:
basePackages:用于指定要扫描的包。和该注解中的 value 属性作用一样。
示例代码: /** * spring 的配置类,相当于 bean.xml 文件 * @Version 1.0 */ @Configuration @ComponentScan("com.itheima") public class SpringConfiguration { } 注意: 我们已经配置好了要扫描的包,但是数据源和 QueryRuner 对象如何从配置文件中移除呢? 请看下一个注解。
3. @Bean
作用:
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。
属性:
name:给当前@Bean 注解方法创建的对象指定一个名称(即 bean 的 id)。
示例代码: /** * 连接数据库的配置类 * @author 黑马程序员 * @Company * @Version 1.0 */ public class JdbcConfig { /** * 创建一个数据源,并存入 spring 容器中 * @return */ @Bean(name="dataSource") public DataSource createDataSource() { try { ComboPooledDataSource ds = new ComboPooledDataSource(); ds.setUser("root"); ds.setPassword("1234"); ds.setDriverClass("com.mysql.jdbc.Driver"); ds.setJdbcUrl("jdbc:mysql:///spring_day02"); return ds; } catch (PropertyVetoException e) { throw new RuntimeException(e); } } /** * 创建一个 QueryRunner,并且也存入 spring 容器中 * @param dataSource * @return */ @Bean(name="runner") @Scope("prototype") public QueryRunner createQueryRunner(DataSource dataSource) { return new QueryRunner(dataSource); } } 注意: 我们已经把数据源和 QueryRunner 从配置文件中移除了,此时可以删除 bean.xml 了。 但是由于没有了配置文件,创建数据源的配置又都写死在类中了。如何把它们配置出来呢? 请看下一个注解。
4 .@PropertySource
作用:
用于加载.properties 文件中的配置。例如我们配置数据源时,可以把连接数据库的信息写到
properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性:
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:
示例代码: 配置: /** * 连接数据库的配置类 * @Version 1.0 */ @PropertySource("classpath:jdbcConfig.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 容器中 * @return */ @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 (PropertyVetoException e) { throw new RuntimeException(e); } } } jdbc.properties 文件: jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/spring_day02 jdbc.username=root jdbc.password=1234 注意: 此时我们已经有了两个配置类,但是他们还没有关系。如何建立他们的关系呢? 请看下一个注解。
5 .@Import
作用:
用于导入其他配置类,在引入其他配置类时,可以不用再写@Configuration 注解。当然,写上也没问
题。
属性:
value[]:用于指定其他配置类的字节码。
示例代码: @Configuration @ComponentScan(basePackages = "com.itheima.spring") @Import({ JdbcConfig.class}) public class SpringConfiguration { } @Configuration//写不写都行 @PropertySource("classpath:jdbc.properties") public class JdbcConfig{ } 注意: 我们已经把要配置的都配置好了,但是新的问题产生了,由于没有配置文件了,如何获取容器呢? 请看下一小节。
6 .通过注解获取容器
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
7.工程结构图
下面是案例演示:
1.创建 maven 工程并导入坐标
1 <dependencies> 2 <dependency> 3 <groupId>junit</groupId> 4 <artifactId>junit</artifactId> 5 <version>4.12</version> 6 <scope>test</scope> 7 </dependency> 8 9 <!--spring单元测试--> 10 <dependency> 11 <groupId>org.springframework</groupId> 12 <artifactId>spring-test</artifactId> 13 <version>5.0.2.RELEASE</version> 14 </dependency> 15 16 <!-- spring框架 --> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-context</artifactId> 20 <version>5.0.2.RELEASE</version> 21 </dependency> 22 23 <dependency> 24 <groupId>commons-dbutils</groupId> 25 <artifactId>commons-dbutils</artifactId> 26 <version>1.4</version> 27 </dependency> 28 29 <dependency> 30 <groupId>mysql</groupId> 31 <artifactId>mysql-connector-java</artifactId> 32 <version>5.1.26</version> 33 </dependency> 34 35 <dependency> 36 <groupId>com.alibaba</groupId> 37 <artifactId>druid</artifactId> 38 <version>1.0.9</version> 39 </dependency> 40 </dependencies>
2.创建数据库和编写实体类
1 public class Account { 2 3 private long id; 4 private String name; 5 private String password; 6 private long money; 7 8 9 public long getId() { 10 return id; 11 } 12 13 public void setId(long id) { 14 this.id = id; 15 } 16 17 18 public String getName() { 19 return name; 20 } 21 22 public void setName(String name) { 23 this.name = name; 24 } 25 26 27 public String getPassword() { 28 return password; 29 } 30 31 public void setPassword(String password) { 32 this.password = password; 33 } 34 35 36 public long getMoney() { 37 return money; 38 } 39 40 public void setMoney(long money) { 41 this.money = money; 42 } 43 44 @Override 45 public String toString() { 46 return "Account{" + 47 "id=" + id + 48 ", name='" + name + '\'' + 49 ", password='" + password + '\'' + 50 ", money=" + money + 51 '}'; 52 } 53 }
3.使用注解配置持久层
1 @Component("accountDao") 2 public class AccountDaoImpl implements AccountDao { 3 @Autowired 4 private QueryRunner queryRunner; 5 6 7 //1.增加账户 8 public int save(Account account){ 9 String sql ="insert into account values (null,?,?,?) "; 10 try { 11 return queryRunner.update(sql,account.getName(),account.getPassword(),account.getMoney()); 12 } catch (SQLException e) { 13 throw new RuntimeException(e); 14 } 15 } 16 17 //2.根据id查询账户信息 18 @Override 19 public Account findById(int id) { 20 String sql ="select * from account where id=?"; 21 try { 22 return queryRunner.query(sql,new BeanHandler<>(Account.class),id); 23 } catch (SQLException e) { 24 throw new RuntimeException(e); 25 } 26 } 27 }
4.使用注解配置业务层
1 @Service 2 public class AccountServiceImpl implements AccountService { 3 @Resource(name="accountDao") 4 private AccountDao accountDao; 5 6 7 //1.增加账户 8 @Override 9 public int save(Account account) { 10 11 return accountDao.save(account); 12 } 13 14 //2.根据id查询账户 15 @Override 16 public Account findById(int id) { 17 return accountDao.findById(id); 18 } 19 }
5.创建并编写配置类
1 //主配置文件 2 @ComponentScan({"com.itheima.service","com.itheima.dao"}) 3 @Import(DaoConfig.class) 4 public class Config { 5 6 }
1//子配置文件
@PropertySource("classpath:db.properties") 2 public class DaoConfig { 3 @Value("${jdbc.driver}") 4 private String driver; 5 @Value("${jdbc.url}") 6 private String url; 7 @Value("${jdbc.username}") 8 private String username; 9 @Value("${jdbc.password}") 10 private String password; 11 @Bean 12 public QueryRunner getQueryRunner(DataSource dataSource) { 13 QueryRunner queryRunner = new QueryRunner(dataSource); 14 return queryRunner; 15 } 16 17 @Bean 18 19 public DataSource getDataSource() { 20 DruidDataSource dataSource = new DruidDataSource(); 21 dataSource.setDriverClassName(driver); 22 dataSource.setUrl(url); 23 dataSource.setUsername(username); 24 dataSource.setPassword(password); 25 return dataSource; 26 } 27 }
1 #db.properties文件 2 jdbc.url=jdbc:mysql:///heima?characterEncoding=utf-8 3 jdbc.driver=com.mysql.jdbc.Driver 4 jdbc.username=root 5 jdbc.password=root
6.测试类
1 public class AppTest { 2 3 4 @Test 5 public void test() { 6 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); 7 AccountService accountService = context.getBean(AccountService.class); 8 9 Account user = accountService.findById(2); 10 System.out.println(user); 11 12 } 13 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?