Spring入门-注解配置
发布日期:2021-05-07 14:44:49 浏览次数:23 分类:原创文章

本文共 15037 字,大约阅读时间需要 50 分钟。



目录


































































注解开发


1 开启注解扫描


<context:component-scan base-package="cn.itcast"></context:component-scan>

2 注解分类


2.1 bean相关注解1



以下注解的功能用于标记指定的类的对象交给spring管理




























注解 描述
@Component 使用在类上用于实例化Bean
@Controller 使用在web层类上用于实例化Bean
@Service 使用在service层类上用于实例化Bean
@Repository 使用在dao类上用于实例化Bean


使用方式1:bean的名字显示指定



@Repository("userDaoImpl")public class UserDaoImpl implements UserDao{
}


使用方式2:bean的名字由框架默认设置,省略bean的名字,bean的名字默认是当前类的名字首字母小写,代码中这个bean的名字其实就是userDaoImpl



@Repositorypublic class UserDaoImpl implements UserDao{
}

2.3 Bean相关注解2(了解)



























注解 描述
@Primary 设置类对应的bean按类型装配时优先装配,,比如如果有多个dao实现类,service要根据类型注入,为了提高dao的优先级,可以在类上加该注解
@DependsOn 控制bean的加载顺序,使其在指定bean加载完毕后再加载
@Order 控制配置类的加载顺序
@Lazy 控制bean的加载时机,使其延迟加载


@Primary



位置:类定义上方


作用:设置类对应的bean按类型装配时优先装配


范例:


@Primarypublic class ClassName{
}


  • 说明:



    • @Autowired默认按类型装配,当出现相同类型的bean,使用@Primary提高按类型自动装配的优先级,多个@Primary会导致优先级设置无效

    1592545826198




依赖加载



(1)@DependsOn


类型:类注解、方法注解


位置:bean定义的位置(类上或方法上)


作用:控制bean的加载顺序,使其在指定bean加载完毕后再加载


范例:


@DependsOn("beanId")public class ClassName {
}

说明:


配置在方法上,使@DependsOn指定的bean优先于@Bean配置的bean进行加载


配置在类上,使@DependsOn指定的bean优先于当前类中所有@Bean配置的bean进行加载


配置在类上,使@DependsOn指定的bean优先于@Component等配置的bean进行加载


相关属性


value(默认):设置当前bean所依赖的bean的id



@Order



类型:配置类注解


位置:配置类定义的位置(类上)


作用:控制配置类的加载顺序


范例:


@Order(1)public class SpringConfigClassName {
}


@Lazy



类型:类注解、方法注解


位置:bean定义的位置(类上或方法上)


作用:控制bean的加载时机,使其延迟加载


范例:


@Lazypublic class ClassName {
}


依赖加载应用场景



@DependsOn



  • 微信订阅号,发布消息和订阅消息的bean的加载顺序控制

  • 双11活动期间,零点前是结算策略A,零点后是结算策略B,策略B操作的数据为促销数据。策略B加载顺序与促销数据的加载顺序


@Lazy



  • 程序灾难出现后对应的应急预案处理是启动容器时加载时机


@Order



  • 多个种类的配置出现后,优先加载系统级的,然后加载业务级的,避免细粒度的加载控制


2.4 依赖注入相关注解



以下注解作用在属性上,完成对属性值的注入




























注解 描述
@Autowired 使用在成员变量上,会根据类型依赖注入。
@Qualifier 结合@Autowired一起使用,根据名称依赖注入
@Resource 相当于@Autowired+@Qualifier,按照名称进行注入,JDK1.9之后不能使用
@Value 注入普通属性


注意1



@Resource(name=”bean名”)在JDK1.9中使用后无法注入,不建议使用



注意2



Autowired根据类型匹配,换句话说就是一个接口如果有多个实现类就必须配合Qualifier一起使用了


img



注意3



Qualifier必须配合@Autowired一起使用,当某个接口的实现类有多个的时候配合该注解使用
1592545895441


2.5 配置单例和多例注解















注解 描述
@Scope 标注Bean的作用范围,该注解配合@Component,@Controller,@Service,@Repository使用

2.6 生命周期相关注解



注意:以下注解JDK1.9不能用




















注解 描述
@PostConstruct 该注解标注在方法上,该方法会在Bean创建的时候执行
@PreDestroy 该注解标注在方法上,该方法会在Bean销毁的时候执行

2.7 替换applicationContext相关注解































注解 描述
@Configuration 替换applicationContext.xml文件
@ComponentScan 替换包扫描context:component-scan
@Bean 替换bean标签
@PropertySource 替换<context:property-placeholder location=”classpath:jdbc.properties”>
@Import 替换<import resource="xxx.xml"></import>标签导入其他的configuration

在这里插入图片描述


2.8 全注解开发步骤



1.编写专门操作数据库的相关配置



package com.itheima.cofig;import com.mchange.v2.c3p0.ComboPooledDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;import java.beans.PropertyVetoException;@PropertySource("classpath:jdbc.properties")public class DataSourceConfiguration {
@Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean("dataSource") //替代<bean id="dataSource"> public DataSource getDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(username); dataSource.setPassword(password); return dataSource; }}


2.编写替换applicationContext.xml的类



package com.itheima.cofig;import com.mchange.v2.c3p0.ComboPooledDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.*;import javax.sql.DataSource;import java.beans.PropertyVetoException;//标志该类是Spring的核心配置类@Configuration//<context:component-scan base-package="com.itheima"/>@ComponentScan("com.itheima")//<import resource=""/>@Import({
DataSourceConfiguration.class})public class SpringCofiguration {
}


3.编写测试方法



public static void main(String[] args) {
//ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); ApplicationContext app = new AnnotationConfigApplicationContext(SpringCofiguration.class); UserService userService = app.getBean(UserService.class); userService.save();}


注意事项



1.@Bean注解必须给一个bean的名字


2.SpringCofiguration是主配置文件,引入了DataSourceConfiguration配置,所以在DataSourceConfiguration类上可以省略@Configuration注解,该注解在主配置文件配置一次就够了,当然每个配置文件都配置也没有任何问题


2.9 注解方式和XML方式配置对比


img


3 集成junit


3.1 为什么要集成junit


1.每次需要手动加载配置文件创建ApplicationContext对象


2.调用getBean方法获取bean


3.getBean方法返回的是Object对象,需要强转


3.2 集成junit的好处


可以直接将我们要使用的bean注入到当前测试类


3.3 使用方式


3.3.1 引入依赖



注意junit版本要大于等于4.12,否则会报如下错误



img


<dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-test</artifactId>    <version>5.0.5.RELEASE</version></dependency><dependency>    <groupId>junit</groupId>    <artifactId>junit</artifactId>    <version>4.12</version>    <scope>test</scope></dependency>

3.3.2 junit测试类上加注解



注解功能


@RunWith是个运行器,SpringJUnit4ClassRunner表示运行在Spring的开发环境中,里面自带applicationContext,所以加上该注解后不需要手动创建applicationContext对象


@ContextConfiguration指定要读取的配置文件



package com.itheima.test;import com.itheima.cofig.SpringCofiguration;import com.itheima.service.UserService;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.sql.DataSource;import java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")public class SpringJunitTest {
}

3.3.3 在测试类中注入要使用的bean


package com.itheima.test;import com.itheima.cofig.SpringCofiguration;import com.itheima.service.UserService;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import javax.sql.DataSource;import java.sql.SQLException;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:applicationContext.xml")//导入XML版配置文件//@ContextConfiguration(classes = {SpringConfig.class})//导入注解版配置文件public class SpringJunitTest {
@Autowired private UserService userService;//测试使用 @Autowired private DataSource dataSource;//测试使用 @Test public void test1() throws SQLException {
userService.save(); System.out.println(dataSource.getConnection()); }}

4 注解方式整合


4.1 第一步 引入依赖


需要引入mysql,mybatis,spring,druid连接池,以及整合mybatis和spring的依赖


<dependencies>    <!--Lombok-->    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>        <version>1.18.4</version>    </dependency>    <!--Spring核心-->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context</artifactId>        <version>5.0.5.RELEASE</version>    </dependency>    <!--Spring集成Junit测试-->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>        <version>5.0.5.RELEASE</version>    </dependency>    <!--Spring集成Aspect切面-->    <dependency>        <groupId>org.aspectj</groupId>        <artifactId>aspectjweaver</artifactId>        <version>1.8.13</version>    </dependency>    <!--Spring 事物-->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-tx</artifactId>        <version>5.0.5.RELEASE</version>    </dependency>    <!--mybatis-->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>3.5.3</version>    </dependency>    <!--mysql-->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.46</version>    </dependency>    <!--spring连接数据库-->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-jdbc</artifactId>        <version>5.1.6.RELEASE</version>    </dependency>    <!--数据库连接池-->    <dependency>        <groupId>com.alibaba</groupId>        <artifactId>druid</artifactId>        <version>1.1.21</version>    </dependency>    <!--spring集成mybatis-->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis-spring</artifactId>        <version>1.3.0</version>    </dependency></dependencies>

4.2 第二步 创建数据库


/*SQLyog Ultimate v12.09 (64 bit)MySQL - 5.5.40 : Database - spring01**********************************************************************//*!40101 SET NAMES utf8 */;/*!40101 SET SQL_MODE=''*/;/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;CREATE DATABASE /*!32312 IF NOT EXISTS*/`spring01` /*!40100 DEFAULT CHARACTER SET utf8 */;USE `spring01`;/*Table structure for table `account` */DROP TABLE IF EXISTS `account`;CREATE TABLE `account` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `name` varchar(24) DEFAULT NULL,  `money` double(10,2) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*Data for the table `account` */insert  into `account`(`id`,`name`,`money`) values (1,'jack',1000.00),(2,'tom',1000.00),(3,'rose',1000.00);/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

4.3 第三步 创建dao\service\domain



创建实体类 Account



package cn.itcast.domain;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class Account {
private Integer id; private String name; private Double money;}


创建 Dao



package cn.itcast.dao;import cn.itcast.domain.Account;import org.apache.ibatis.annotations.Select;import java.util.List;public interface AccountDao {
@Select("select * from account") List<Account> findAll();}


创建Service



package cn.itcast.service;import cn.itcast.domain.Account;import java.util.List;public interface AccountService {    List<Account> findAll() ;}


创建Service实现类



package cn.itcast.service.impl;import cn.itcast.dao.AccountDao;import cn.itcast.domain.Account;import cn.itcast.service.AccountService;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.util.List;public class AccountServiceImpl implements AccountService {
private AccountDao accountDao; public List<Account> findAll() {
return accountDao.findAll(); } public AccountDao getAccountDao() {
return accountDao; } public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao; }}

4.4 第四步 创建jdbc.properties


jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/spring01jdbc.username=rootjdbc.password=root

4.5 第五步 创建数据库连接池的配置文件


package cn.itcast.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import javax.sql.DataSource;//声明当前java类是配置文件@Configuration//引入jdbc.properties配置文件@PropertySource("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; //创建数据库连接池的bean对象,并交给srping容器管理 @Bean public DataSource getDataSource(){
DruidDataSource druidDataSource = new DruidDataSource(); druidDataSource.setUsername(this.username); druidDataSource.setPassword(this.password); druidDataSource.setUrl(this.url); druidDataSource.setDriverClassName(this.driver); return druidDataSource; }}

4.6 第六步 创建整合MyBatis的配置文件


package cn.itcast.config;import org.mybatis.spring.SqlSessionFactoryBean;import org.mybatis.spring.mapper.MapperScannerConfigurer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configurationpublic class MyBatisConfig {
@Bean public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setTypeAliasesPackage("cn.itcast.domain"); sqlSessionFactoryBean.setDataSource(dataSource); return sqlSessionFactoryBean; } @Bean public MapperScannerConfigurer getMapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); mapperScannerConfigurer.setBasePackage("cn.itcast.dao"); return mapperScannerConfigurer; }}

4.7 第七步 创建主配置文件


package cn.itcast.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;@Configuration@ComponentScan("cn.itcast")@Import({
JdbcConfig.class,MyBatisConfig.class})public class AppConfig {
}

4.8 第八步 配置Service层


自定义类,如果需要交由Spring管理,添加 @Component,@Controller,@Service,@Repository 等注解


本案例在Service的实现类上添加注解


package cn.itcast.service.impl;import cn.itcast.dao.AccountDao;import cn.itcast.domain.Account;import cn.itcast.service.AccountService;import lombok.Data;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Service("accountService")public class AccountServiceImpl implements AccountService {
@Autowired private AccountDao accountDao ; public List<Account> findAll() {
return accountDao.findAll(); } public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao; }}

4.9 第九步 编写测试类


import cn.itcast.config.AppConfig;import cn.itcast.domain.Account;import cn.itcast.service.AccountService;import org.junit.Test;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class AppTest {
@Test public void findAll(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); AccountService accountService = applicationContext.getBean(AccountService.class); List<Account> all = accountService.findAll(); System.out.println(all); }}

5 面试题


BeanFactory和FactoryBean的区别



  • FactoryBean:封装单个bean的创建过程,提供了了一些方法比如获取当前bean,判断是否是单例,获取当前bean的类型。目的是为了创建某些复杂的bean

  • BeanFactory:Spring容器顶层接口,定义了bean相关的获取操作

上一篇:Spring进阶-AOP配置xml
下一篇:Spring入门-IOC和XML配置

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2025年03月21日 03时18分11秒