
本文共 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会导致优先级设置无效
依赖加载
(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一起使用了
注意3
Qualifier必须配合@Autowired一起使用,当某个接口的实现类有多个的时候配合该注解使用
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方式配置对比
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,否则会报如下错误
<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相关的获取操作
发表评论
最新留言
关于作者
