创建 bean
public class Student {
}
配置 xml bean
获取 bean
@Test
public void testXmlBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("xmlbeans.xml");
final Student student = (Student)context.getBean("student");
System.out.println(student);
}
注入属性也比较麻烦:构造器,setter
public interface UserMapper {
void save();
}
public class UserMapperImpl implements UserMapper {
public void save() {
System.out.println("保存用户成功");
}
}
使用 @Component 注解,配置 mapper 实现类
@Component
public class UserMapperImpl implements UserMapper {
public void save() {
System.out.println("保存用户成功");
}
}
配置 xml 包扫描路径
获取 applicationContext
@Test
public void testComponent(){
ApplicationContext context = new ClassPathXmlApplicationContext("xmlAndAnnotation.xml");
final UserMapper bean = context.getBean(UserMapper.class);
bean.save();
}
正规命名的时候:UserMapperImpl --- userMapperImpl
不正规命名时候:UUserMapperImpl--- UUserMapperImpl
@Component("u") 参数就是你bean的名称
Controller(控制层)
@Controllerpublic class UserController { //写接口}
Service(业务层)
@Service
public class UserServiceImpl implements IUserService {
public void save() {
}
}
Repository(持久层)
@Repository
public class UserMapperImpl implements UserMapper {
public void save() {
System.out.println("保存用户成功");
}
}
配置学生Mapper
mapper 接口
public interface StudentMapper {
void save();
}
mapper 接口实现类
@Repository
public class StudentMapperImpl implements StudentMapper {
public void save() {
System.out.println("保存学生成功");
}
}
添加配置类
@Configuration
public class SpringConfig {
}
将 SpringConfig 类变成spring 的配置类,替换 xml 配置文件
作用:标识该类是spring的配置类
配置名称,默认首字母小写
使用在类上
配置包扫描 @ComponentScan
@Configuration
@ComponentScan("cn.sycoder.annotationBean.mapper")
public class SpringConfig {
}
作用:配置包扫描路径,当前包及其子包都会扫描
value:指定包的路径,用于扫描并且注册bean
获取 applicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
获取 bean
@Test
public void testAnnotation(){
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println(context);
final StudentMapper bean = context.getBean(StudentMapper.class);
System.out.println(bean);
}
配置类
@Configuration
@ComponentScan({"cn.wjcoder.xmlAnnotationBean"})
public class ScopesConfig {
}
配置 bean
@Component
public class ScopeBean {
}
获取 bean 执行发现bean 单例的
@Test
public void testScope(){
ApplicationContext context = new AnnotationConfigApplicationContext(ScopesConfig.class);
final ScopeBean bean = context.getBean(ScopeBean.class);
final ScopeBean bean1 = context.getBean(ScopeBean.class);
System.out.println(bean);
System.out.println(bean1);
}
@Component
@Scope("prototype")
public class ScopeBean {
}
@Component
public class LifeBean {
public LifeBean(){
System.out.println("构造器执行了");
}
@PostConstruct
public void init(){
System.out.println("初始化bean");
}
@PreDestroy
public void destroy(){
System.out.println("销毁bean");
}
}
位置:方法上
作用:设置该方法为初始化方法
位置:方法上
作用:设置该方法为销毁方法
建立 mapper
public interface EmployeeMapper {
void save();
}
建立 mapper 实现类
@Repository
public class EmployeeMapperImpl implements EmployeeMapper {
public void save(){
System.out.println("保存员工信息");
}
}
建立 service
public interface IEmployeeService {
void save();
}
建立 service 实现类
@Service
public class EmployeeServiceImpl implements IEmployeeService {
private EmployeeMapper employeeMapper;
public void setEmployeeMapper(EmployeeMapper employeeMapper){
this.employeeMapper = employeeMapper;
}
public void save() {
employeeMapper.save();
}
}
设置配置类
@Configuration
@ComponentScan("cn.sycoder.di.di01")
public class DiConfig {
}
出现空指针异常
通过构造器注入
@Autowired
public EmployeeServiceImpl(EmployeeMapper employeeMapper) {
this.employeeMapper = employeeMapper;
}
通过setter 方法注入
@Autowired
public void setEmployeeMapper(EmployeeMapper employeeMapper) {
this.employeeMapper = employeeMapper;
}
直接在属性上使用(是以后用得最多的)
@Service
public class EmployeeServiceImpl implements IEmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
public void save() {
employeeMapper.save();
}
}
注意:不提供setter 方法以及构造器是使用反射创建对象的
@Test
public void autowired() throws Exception {
final Class> aClass = Class.forName("cn.wjcoder.di.di01.service.EmployeeServiceImpl");
final Object o = aClass.newInstance();
final Field[] fields = aClass.getDeclaredFields();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DiConfig.class);
final EmployeeMapper bean = context.getBean(EmployeeMapper.class);
for (Field field : fields) {
field.setAccessible(true);
field.set(o,bean);
}
final EmployeeServiceImpl service = (EmployeeServiceImpl) o;
service.save();
}
根据类型注入必须只有一个实现类,否则会报错,添加名称也不行
属性required=false,如果找不到不会报错
@Autowired & @Qualifier
@Autowired & @Qualifier必须同时使用,缺一不可
解决刚才出现两个实现类没法注入的问题
配置mapper 并且指定实现类的名称
public interface EmployeeMapper {
void save();
}
@Repository("empMapper1")
public class EmployeeMapperImpl implements EmployeeMapper{
@Override
public void save() {
System.out.println("保存员工信息");
}
}
@Repository("empMapper2")
public class EmployeeMapperImpl1 implements EmployeeMapper {
private EmployeeMapper employeeMapper;
public void save() {
employeeMapper.save();
}
}
@Service
public class EmployeeServiceImpl implements IEmployeeService {
@Autowired(required = false)
@Qualifier("empMapper1")
private EmployeeMapper employeeMapper;
public void save() {
employeeMapper.save();
}
}
@Value
修改配置类
@Configuration
@ComponentScan("cn.wjcoder.di.di01")
@PropertySource("db.properties")
public class DiConfig {
}
修改获取方式使用 ${} 的方式
@Component
public class DbProperties {
@Value("${username}")
private String username;
@Value("${password}")
private String password;
public void test(){
System.out.println(username + ":" + password);
}
}
@PropertySource 加载配置文件
位置:配置类上
作用:导入配置文件
对于多个配置文件
@Configuration
@ComponentScan("cn.wjcoder.di.di01")
@PropertySource({"db.properties","xx.properties"})
public class DiConfig {
}
添加依赖
com.alibaba
druid
1.2.8
先添加配置类 SpringConfig
@Configuration
public class SpringConfig {
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername("root");
source.setPassword("123456");
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/mybatis");
return source;
}
}
传统做法存在硬编码,DataSource 并且没有交给 spring 管理,每次都需要重新新建 DataSource ,并不存在单例一说
@Test
public void testDruid(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
final SpringConfig bean = context.getBean(SpringConfig.class);
System.out.println(bean.dataSource());
}
使用@Bean 交给 spring 管理
@Configuration
public class SpringConfig {
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername("root");
source.setPassword("123456");
source.setDriverClassName("com.mysql.cj.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/mybatis");
return source;
}
}
修改配置的硬编码改成软编码
@Configuration
@PropertySource("druidDb.properties")
public class SpringConfig {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
@Bean 与 xml 对应
目前存在:任何类都配置到配置类里面,不方便管理,也不方便维护
@Component
@Component
public class DruidConfig {
@Value("{jdbc.username}")
private String username;
@Value("{jdbc.password}")
private String password;
@Value("{jdbc.url}")
private String url;
@Value("{jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
修改druidConfig
@Configuration
public class DruidConfig {
@Value("{jdbc.username}")
private String username;
@Value("{jdbc.password}")
private String password;
@Value("{jdbc.url}")
private String url;
@Value("{jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
修改spring配置类
@Configuration
@PropertySource("druidDb.properties")
@Import({DruidConfig.class})
public class SpringConfig {
}
如果需要传参,只需要将参数交给spring管理就行了
@Configuration
public class RepositoryConfig {
@Bean
public AccountRepository accountRepository(DataSource dataSource) {
return new JdbcAccountRepository(dataSource);
}
}
注解配置 | xml 配置 | 功能说明 |
---|---|---|
@Component @Controller @Service @Repository |
bean 标签(id,class) | 定义bean |
@ComponentScan | 扫描包加载bean | |
@Autowired @Qualifier @Value |
setter 注入 构造器注入 自动装配 |
依赖注入 |
@Bean | bean 标签, 静态工厂模式, 实例工厂模式, FactoryBean |
配置第三方bean |
@Scope | bean 标签中的 scope 属性 | 设置作用域 |
@PostConstructor @PreDestroy |
bean 标签中的 init-method / destroy-method | 生命周期相关 |
@Import | 导入其它的配置类 | |
@PropertySource({"db.properties","xx.properties"}) | 导入配置文件 |
org.springframework
spring-context
5.2.17.RELEASE
junit
junit
4.12
test
org.springframework
spring-test
5.2.7.RELEASE
@Repository
public class StudentMapperImpl implements StudentMapper {
public void save() {
System.out.println("保存操作");
}
}
@Configuration
@ComponentScan("cn.sycoder")
public class SpringConfig {
}
先建立测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfig.class})
public class StudentTest {
@Autowired
private StudentMapper studentMapper;
@Test
public void testStudentMapper(){
studentMapper.save();
}
}
说明 | @Runwith |
---|---|
位置 | 测试类上方 |
作用 | 测试类注解,设置 junit 运行器的 |
属性 | 使用测试运行的环境,SpringJUnit4ClassRunner.class |
说明 | @ContextConfiguration |
---|---|
位置 | 测试类上方 |
作用 | 设置 junit 加载 spring 配置类 |
属性 | classes:核心配置类,可以传入多个 locations:配置文件的文件路径名称 |
概述:jdbcTemplate 是 spring 对于学过的 jdbc 的封装,实现了方便操作数据库
org.springframework
spring-orm
5.2.17.RELEASE
mysql
mysql-connector-java
8.0.29
com.alibaba
druid
1.2.8
org.projectlombok
lombok
1.18.22
创建配置文件
jdbc.username=root
jdbc.password=123456
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
配置类
@Configuration
@PropertySource("jdbc.properties")
public class DruidConfig {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
}
@Configuration
@PropertySource("jdbc.properties")
public class DruidConfig {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driverClassName}")
private String driver;
@Bean
public DataSource dataSource(){
final DruidDataSource source = new DruidDataSource();
source.setUsername(username);
source.setPassword(password);
source.setDriverClassName(driver);
source.setUrl(url);
return source;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
return jdbcTemplate;
}
}
修改保存
@Repository
public class StudentMapperImpl implements StudentMapper {
@Autowired
private JdbcTemplate template;
public void save() {
String sql = "insert into student value(null,?,?)";
template.update(sql,"sy",18);
}
public Student getById(Long id) {
Object student = template.queryForObject("select * from student where id = ?",
new BeanPropertyRowMapper(Student.class), id);
return (Student) student;
// return null;
}
}