注解IOC
@Component
用来代替xml模式创建对象
有两种使用方法(都是定义在class类定义之上)
1.直接@Component, id的默认值是类名首字母小写
2.@Component("id值")
@Controller: 一般用于表现层的注解。 同@Component
@Service: 一般用于业务层的注解。 同@Component
@Repository: 一般用于持久层的注解。 同@Component
@Component: 除了上述情形以外的工具类,使用此注解。
功能都一样,起不不同的名字的是为了增加可读性
注解IOC-DI:注入数据@Autowired修饰字段
作用是给对象的属性进行赋值
修饰在字段上,自动装配,可以自动根据字段的类型或名称进行注入
注解写在对象属性定义之上
@Autowired查找注入过程
1.从IOC容器中查找相同类型的对象注入,如果没有找到抛出异常,找到多个型也抛出异常
2.如果没有找到对应类型或者是找到多个类型就会根据字段名字查找,如果没有找到抛出异常,找到多个也抛出异常
使用方式
第一种:@Autowired 【推荐】
第二种:@Autowired(required = false)
required=true, 默认值,代表必须从IOC容器中找到一个合适的对象给字段注入数据,找不到抛出异常
required=false, 代表如果找不到,赋值为null
@Qualifier注解可以让@AutoWired注解按照指定名称注入
在jdk1,8之前有ioc@Resourece注入,jdk9开始就没有,实现了自动注入和按名称注入,相等于前两者相加
@value
作用:用来设置默认值
格式一:直接赋值
格式二:使用spring的EL表达式
这个注解不是从ioc容器中获得值,就是直接赋值
对象范围与生命周期相关注解
@Scope 【对象范围】
@PostConstruct 【修饰初始化方法,创建对象之后执行】
@PreDestroy 【修饰回收资源方法,销毁容器之前执行】
@Lazy 【延迟初始化】
"true"设置对象在第一次获取的时候才创建,在单例模式下有效,默认为false
对比xml:
<bean id="" class="" 对应的注解:@Controller、@Servvice、@Repository、@Component
scope="" 使用@Scope注解取代
init-method="" 使用@PostConstruct注解取代
destroy-method="" 使用@PreDestroy注解取代
lazy-init="" /> 使用@Lazy注解取代
注解改造,
企业上的原则:自己的代码用注解,别人的代码用xml方式
基于纯注解
用注解代替所有xml
@Configuration 用于指定当前类是一个是spring配置类当创建容器时会从该类上加载注解。 获取容器时需要使用AnnotationApplicationContext(有@Configuration 注解的类.class)。
@ComponentScan用于指定 spring 在初始化容器时要扫描的包。
作用和在 spring 的 xml 配置文件中的:<context:component-scan base-package="cn.itcast"/>是一样的。
@Bean 该注解写在方法上,表明这个方法创建一个对象,并放入 IOC容器中
@Proper't'ySource 用于加载properties配置文件
@Import 用于导入
部分代码演示
原来的xml配置信息:文件名:applicationContext.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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启IOC注解扫描-->
<context:component-scan base-package="com.itheima"></context:component-scan>
<!--读取properties文件的标签-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--1.创建DruidDataSource对象-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--2.创建JdbcTemplate对象,注入DruidDataSource对象-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--<import resource="classpath:xxxx.xml"></import>-->
</beans>
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author
*/
@Configuration //作用:代替配置文件applicationContext.xml,说明当前是spring配置文件类
@ComponentScan(basePackages = {"com.itheima"}) //作用:基包扫描,代替 <context:component-scan base-package="com.itheima"></context:component-scan>
@Import(JdbcConfig.class) //作用:代替<import resource="classpath:xxxx.xml"></import>导入其他配置文件
public class SpringConfiguration {
}
实现了代替spring文件,说明当前这个类是spring配置文件,代替了包扫描,代替了引入文件
package config;
import com.alibaba.druid.pool.DruidDataSource;
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.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* JdbcConfig职责
* 1.加载外部的jdbc.properties配置文件的数据
* 2.创建DataSource对象
* 3.创建JdbcTemplate对象
*/
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
//读取jdbc.properties,对字段进行赋值
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//创建DataSource对象
/*
* @Bean
* 作用:将方法的返回值加入IOC容器
* 使用格式:
* 格式1:@Bean 加入IOC容器,id属性名默认类名首字母小写
* 格式1:@Bean("id的属性名"), 加入IOC容器,并且设置指定的id属性名
* */
@Bean("dataSource1")
public DataSource createDataSource1(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
@Bean("dataSource2")
public DataSource createDataSource2(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
//3.创建JdbcTemplate对象
@Bean //@Bean 注解使用的方法的参数变量会从IOC容器中获取对象,默认先根据类型查找,如果查找到多个会根据参数名查找
public JdbcTemplate createJdbcTemplate(@Qualifier("dataSource2") DataSource dataSource){ //@Qualifier单独使用的方式,根据指定id属性名查找注入
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
}
代码实现了代替jdbc的读取标签和<Bean>表签,使用values()对字段进行了赋值
纯注解测试类
代码演示
package com.itheima.test;
import com.itheima.entity.Account;
import com.itheima.service.AccountService;
import config.SpringConfiguration;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
/**
* @author
*/
public class AppTest {
@Test
public void test(){
//1.创建IOC容器对象
//ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
**ApplicationContext act = new AnnotationConfigApplicationContext(SpringConfiguration.class);**
//2.获取业务类对象
AccountService accountService = act.getBean(AccountService.class);
//3.执行数据库查询操作
List<Account> accountList = accountService.findAll();
//4.打印结果
accountList.forEach(System.out::println);
}
}
代码使用AnnotationConfigApplicationContext对配置类进行了反射处理
Spring整合Junit
应用
-
只是为了简化测试而已。
-
如果要用spring整合junit,需要先引入spring-test包
<!--Spring对junit支持包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
- 纯注解开发,Spring整合Junit测试:
package com.itheima.test;
import com.itheima.entity.Account;
import com.itheima.service.AccountService;
import config.SpringConfiguration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* Spring整合junit,目的使用测试类的时候就创建好了IOC容器对象
*/
public class AppTest2 {
@Autowired
AccountService accountService;
@Test
public void test(){
//执行数据库查询操作
List<Account> accountList = accountService.findAll();
//打印结果
accountList.forEach(System.out::println);
}
}
- XML配置,Spring整合Junit测试:
package com.itheima.test;
import com.itheima.entity.Account;
import com.itheima.service.AccountService;
import config.SpringConfiguration;
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 java.util.List;
/**
* Spring整合junit,目的使用测试类的时候就创建好了IOC容器对象
*/
@RunWith(SpringJUnit4ClassRunner.class) //先运行spring的测试类
@ContextConfiguration("classpath:applicationContext.xml") //加载spring配置文件,创建IOC容器对象
public class AppTest3 {
@Autowired
AccountService accountService;
@Test
public void test(){
//执行数据库查询操作
List<Account> accountList = accountService.findAll();
//打印结果
accountList.forEach(System.out::println);
}
}
@RunWith 用于指定启动时候创建容器的工具类
@ContextConfiguration 指定容器的XML配置文件路径或者注解类的字节码类型创建IOC容器对象