Spring中使用注解开发
注解概念
在spring配置文件中加上context标签
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com"/>
</beans>
<context:component-scan base-package=“com”/>base-package的属性写包名,spring会通过这个包名去扫描这个包下的所有文件
- 在进行包扫描时,会对配置的包下所有子包的文件进行扫描
- 扫描是以文件夹递归形式迭代的形式进行的
- 扫描过程中仅读取合法的java文件
- 扫描时仅读取spring可识别的注解
- 扫描结束后会将所有spring可识别的注解转化为spring对应的资源放入IoC容器中
注:无论是注解方式还是配置文件方式,最后都会将资源放入IOC容器中,仅仅是数据读取方式不一样,从加载效率上来说,注解方式优于xml配置方式
bean定义常用注解
要使用spring注解方式管理自己所写的类使用以下注解,这些注解全部都是写在类上方,所有的注解都有一个value属性(可以省略value),就相当于配置方式的id属性
- Component(一般的类使用这个注解)
- Repository(一般写在dao层的类上方)
- Service(一般写在业务层的类上方)
- Controller(一般写在表现层的类上方)
@Component
public class ClassName {
}
- Scope注解,相当于配置方式的scope属性,默认是单例(singleton),想变成多例写在注解Component下方,赋上prototype。
注解配置第三方资源(工厂加载bean的形式)
@Bean,这个注解是一个方法注解,写在方法上方,作用是设置这个方法的返回值作为spring管理的bean,因为第三方的资源无法在源码中写注解,只能通过bean注解解决第三方引入bean的问题,@Bean注解所在的类必须被spring扫描到,否则此注解无法生效,这个注解也有一个value属性,可以省略,定义bean的访问id
@Component("className")
public class ClassName {
@Bean("dataSource")
public DataSource getDataSource(){
return new DruidDataSource();
}
}
属性注入常用注解
- value
属性定义的上方,方法的上方
value值仅支持对非引用数据类型的赋值
value支持读取配置文件properties的属性,通过类属性将properties中的数据传入类中
value注解如果写在成员变量上方,可以省略set方法
@Value("1")
private Integer id;
@Value("张三")
private String name;
@Value("1.99")
private Double money;
- Autowired
属性定义的上方,方法的上方
支持对引用数据类型的赋值
@Autowired
private AccountDao accountDao;
不用指定名字,spring会自动装配此类型的实现类,如果这个接口有两个实现类都交给了spring管理,会优先引用id值和变量名一样的类,如果想指定哪个实现类优先,在实现类下面加上注解@primary,spring就是优先引用这个实现类,如果id值没有为accountDao的值,则会报错。
- Qualifier
这个注解也试用来给引用类型的成员变量赋值的,不同的地方是这个注解可以指定参数(这个参数就是实现类对应的id值)。
@Qualifier("accountDao1")
private AccountDao accountDao;
这种方式只会匹配id值为accountDao的对应的实现类。
加载properties文件中的属性
- PropertySource
写在类的上方,不支持*通配格式,一旦加载,spring管理的bean都可以通过${属性名}使用这个配置文件的属性,这个注解有一个value属性classpath:后面加配置文件的名字,如果有多个文件用逗号隔开。
@PropertySource("classpath:fileName.properties")
public class ClassName {
}
注解类的设计
- Configuration
设置当前的类为spring核心配置加载类,类中可以什么都不写
- ComponentScan
bean扫描使用这个注解替代,参数写要扫描的包名
- 要替换的方法(AnnotationConfigApplicationContext)
之前使用配置文件的方式需要先读取配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext(配置文件的名字);
因为现在已经把一个类设置成了注解类,所以不需要配置文件的方式,可以把配置文件删除,全部使用注解。
ApplicationContext ctx = new AnnotationConfigApplicationContext(注解类的class)
@Configuration
@ComponentScan("com")
public class SpringConfig {
}
如何导入第三方资源对应的配置类
- import
类定义的上方
作用:导入第三方的bean作为spring控制的资源
这个注解在同一个类中只能定义一次,如果有多个bean需要导入,用数组的方式,@Bean所在的类无需声明为bean,可以直接用import导入。参数是类的class文件
用注解的方式整合mybatis
用配置文件的方式整合mybatis
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com"/>
<!--加载perperties配置文件的信息-->
<context:property-placeholder location="classpath:*.properties"/>
<!--加载druid资源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--配置service作为spring的bean,注入dao-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<!--spring整合mybatis后控制的创建连接用的对象-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.itheima.domain"/>
</bean>
<!--加载mybatis映射配置的扫描,将其作为spring的bean进行管理-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.dao"/>
</bean>
</beans>
如果要使用注解的方式整合mybatis,就相当于要把这些标签提供的bean全部用注解的方式呈现出来
- 需要的jar包
- mysql
- druid
- mybatis
- spring
- spring-jdbc
- mybatis-spring
2.创建一个类,设置为spring的注解类
@Configuration
@ComponentScan("com")
public class SpringConfig {
}
3.加载配置文件的注解添加到注解类中
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
4.加载druid资源,第三方bean需要使用import注解加载进来,所以要创建一个专门加载druid资源的类
public class JDBCConfig {
@Value("${jdbc.driver}")
private String diverClass;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource getDataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(diverClass);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
5.将mybatis两个最重要的类加载到spring管理,创建一个加载mybatis资源的类
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage("com.itheima.domain");
return sqlSessionFactoryBean;
}
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.itheima.dao");
return mapperScannerConfigurer;
}
}
6.将业务层的实现类交给spring管理,在类上方直接加上注解@Service
7.将这些第三方的bean交给spring进行管理,在注解类加上import注解
@Configuration
@ComponentScan("com.itheima")
@PropertySource("classpath:jdbc.properties")
@Import({JDBCConfig.class,MyBatisConfig.class})
public class SpringConfig {
}
最后将dao层接口的映射文件改成注解
注解整合Junit
如何在Junit中使用spring中的资源?
- Spring接管Junit的运行权,使用Spring专用的Junit类加载器
- 为Junit测试用例设定对应的spring容器
注:在spring5.0以后,junit必须是4.12及以上
- 导包(junit和spring-test)
- 使用spring专门的类加载器@RunWith
- 设定加载的spring上下文对应的配置@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Test
public void test(){
}
}