Spring的注解开发
在开发中,配置文件中Bean标签会非常多,难以维护。怎么
办?
使用注解的形式替代xml配置,可以将一些繁杂的spring配置
从工程中消除掉,简化书写。
注解配置和基于XML配置内容含义是一模一样,可以互相置
换。
实际开发中,到底用 xml 还是注解,各有优劣,所以这两种
配置方式我们都需要掌握。尤其是注解,在未来的
SpringBoot中有很重要的应用。现在需要好好掌握
1.1 半xml半注解开发
我们自己的类使用注解开发,第三方的类使用xml开发
1.1.1 启用注解功能
启动注解扫描
<context:component-scan base-package="packageName"/>
说明:
在进行包所扫描时,会对配置的包及其子包中所有java
文件进行扫描
扫描结束后会将可识别的有效注解转化为spring对应的
资源加入IoC容器
示例
<!-- 扫描com.ll包下所有的类-->
<context:component-scan base-package="com.ll"/>
1.1.2 Bean的定义(@Component)
名称:@Component @Controller @Service @Repository
类型:类注解
位置:类定义上方
作用:设置该类为spring管理的bean
示例:
//@Component
@Service
public class UserServiceImpl implements
UserService{
@Override
public void save() {
System.out.println("service...add...");
}
}
@Controller、@Service 、@Repository是 @Component的衍生注解,功能等同@Component
@Controller 用于Controller层的类 :表现层
@Service 用于Service层的类: 业务层
@Repository 用于Dao层的类: 持久层(一般不写)
相关属性:value(默认),定义bean的访问id。默认的id
名称为 "简单类名,首字母小写"
使用value属性指定bean的id
@Service(value = "userService")
public class UserServiceImpl implements
UserService{
@Override
public void save() {
System.out.println("service...add...");
}
}
当注解中只设置一个属性时,value属性的属性名可以省
略:
@Service("userService")
public class UserServiceImpl implements
UserService{
@Override
public void save() {
System.out.println("service...add...");
}
}
1.1.3 注入Bean(@Autowired)
注解的方式注入bean,不需要setter方法
名称:@Autowired、@Qualifier、@Resource
类型:属性注解、方法注解(了解即可)
位置:可以用在属性上和set方法上, 如果写在属性上,可
以没有set方法
作用:自动装配,设置属性的对象或对方法进行传参(从
IOC容器查找对象, 给属性赋值)
示例:
@Service
public class UserServiceImpl implements
UserService{
@Autowired
private UserDao userDao;
@Override
public void save() {
System.out.println("service...add...");
}
}
说明:
@Autowired 按类型装配,一般生产中都使用它,由
spring提供的,只有引入spring依赖才可使用。
@Qualifier 可以指定bean的id,一般用于有多个同一
类型bean的场景(必须配合@Autowired使用)。
@Resource 相当于同时指定了@Autowired和
@Qualifier,由Jdk提供的,了解即可。
@Service
public class UserServiceImpl implements
UserService{
@Autowired//按类型注入
@Qualifier("userDao")//如果出现一个接口实现两个类 出现冲突的情况下可以通过Qualifier注解指定实
//现的类
private UserDao userDao;
@Override
public void save() {
System.out.println("service...add...");
}
}
相关属性
@Autowired
required:定义该属性是否允许为null,默认true
@Qualifier
value:需要注入的bean的id
@Resource
name:需要注入的bean的id
1.1.4 其他注解(了解即可)
@Primary 类注解(也可以用于方法上,配合@Bean使用),设置bean的优先级
@Autowired默认按类型装配,当出现相同类型的
bean,使用@Primary提高按类型自动装配的优先级,
程序就不会报错了。
@Primary//出现两个类实现一个接口的时候指定这个类为优先级也可以解决两个类实现一个接口的冲突
@Component
public class ClassName{}
@Scope 类注解,设置该类作为bean对应的scope属性
相当于标签的scope属性
// 默认为singleton
@Scope("prototype")
public class ClassName{}
7.2 Spring纯注解开发
spring零配置也就是使用注解完全替代xml 配置文件。
零配置xml就不要了,那么有谁来进行xml的替代? 如何实
现?
替代xml中相关标签的注解是什么?怎么使用?
既然没有xml了,还得创建一个 用来解析注解的容器对象,如
何创建?
7.2.1 零配置IOC容器
加载纯注解格式上下文对象,需要使用
AnnotationConfigApplicationContext
需要创建一个配置包 里面建一个配置类名字就叫ConFig见名知意
// SpringConfig是一个配置类(有@Configuration注解)
ApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.
class);
7.2.2 @Configuration注解
类型:类注解
作用:作用等同于xml配置文件,当前注解声明的类中,编
写配置信息,所以我们把使用@Configuration的类称之
为配置类
实例
//标注当前类是配置类,替代applicationContext.xml
@Configuration
public class MyConfiguration {
}
7.2.3 @ComponentScan注解
类型:类注解
作用:扫描注解,此注解只能添加一次,多个数据请用数
组格式
实例
@Configuration
@ComponentScan({"com.lzw"})
//@ComponentScan({"com.lzw.service","com.lzw.dao"})
public class SpringConfig {……}
相当于XML配置文件中的context:component-scan标签
<context:component-scan base-package="com.lzw"/>
注意:扫描的包路径不写,扫描当前包及其子包!
7.3 Spring整合Druid
7.3.1 @Bean注解
类型:方法注解
作用:将方法的返回值存储到Spring IOC容器中
实例:
//第三方jar包的类,添加到ioc容器,无法使用
@Component等相关注解!
//bean的id可以指定,默认是方法名
@Bean("dataSource")
public DruidDataSource createDataSource(){
//创建数据源对象并返回
DruidDataSource druidDataSource = new
DruidDataSource();
druidDataSource.setDriverClassName(driverClassN
ame);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
这一步:相当于XML配置文件中的标签
<bean id="userService" class="com.lzw.service.UserServiceImpl"></bean>
7.3.2 @Value注解、
类型:属性注解、方法注解(了解)
作用:注入非引用类型,设置属性的值或对方法进行传参
范例:
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
结合:
@PropertySource({"classpath:db.properties"})//加载数据库配置文件
public class JdbcConfig {
@Value("${jdbc.driver}")//Value注解获取配置文件里面数据库的值并赋值给下面的变量
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//第三方jar包的类,添加到ioc容器,无法使用
@Component等相关注解!
//bean的id可以指定,默认是方法名
@Bean("dataSource")
public DruidDataSource createDataSource(){
//创建数据源对象并返回
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
说明:
@value一般用于读取properties文件中的属性值
注解的方式注入非引用类型,不需要setter方法
相关属性
value(默认):定义对应的属性值或参数值
7.3.3 @Import注解
类型:类注解
作用:导入其他配置类(对象)
使用@Import注解把这个类导入到SpringConfig
范例:
//RedisConfig是另外一个配置类
@Import({JdbcConfig .class})//类名点class导入
public class SpringConfig{
}
相当于XML配置文件中的标签:
<import resource="classpath:applicationContext-dao.xml"/>
7.3.4 @PropertySource注解
位置:标记在类上
注解作用:引入外部属性文件(jdbc.properties),加载多文
件请使用数组格式配置
实例:
//@PropertySource({"classpath:application.properties","classpath:jdbc.properties"})
@PropertySource({"classpath:db.properties"})//上面已经加载
public class JdbcConfig {
}
相当于XML配置文件中的context:property-placeholder标签
<context:property-placeholder
location="classpath:db.properties"/>
1.4 Spring整合JUnit
7.4.1 Spring整合junit的好处
好处一:配置完之后,不需要我们手动创建Spring的容
器,容器由Junit帮我们自动初始化
好处二:可以在junit测试类中使用@AutoWired等方式注
入对象,直接对其进行调用测试
7.4.2 整合实现步骤
*导入依赖坐标
*在测试类上加入@RunWith注解,指定Spring的运行器
*配置初始化Spring容器的配置文件(配置类)
*删除原有的初始化代码ClassPathXmlApplicationContext
*注入Bean,执行测试代码
导入依赖坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
注意:junit的依赖至少要是4.12版本,可以是4.13等版本,否则
会出现异常
代码实现
//在测试类上加入@RunWith注解,指定Spring的运行器
@RunWith(SpringJUnit4ClassRunner.class)
//配置初始化Spring容器的配置文件(配置类)
@ContextConfiguration(classes =
{SpringConfig.class}) //加载配置类
//@ContextConfiguration(locations={"classpath:applicationContext.xml"})//加载配置文件
public class DemoTest {
@Autowired
private UserService userService;
@Test
public void test01(){
userService.save();
}
}
7.5 参考代码
业务层代码
//接口类
public interface UserService {
public void save();
}
//实现类
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public void save() {
System.out.println("service...add...");
userDao.save();
}
}
DAO层代码
public interface UserDao {
public void save();
}
@Repository
public class UserDaoImpl implements UserDao{
@Override
public void save() {
System.out.println("dao...save...");
}
}
配置类
@Configuration
@ComponentScan({"com.lzw"})
@Import({JdbcConfig.class})//导入JdbcConfig配置类
public class SpringConfig {
}
@PropertySource({"classpath:db.properties"})//加载资源文件
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driverClassName;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
// 如何完成把德鲁伊对象交给spring管理
@Bean
public DruidDataSource createDataSource(){
//创建数据源对象并返回
DruidDataSource druidDataSource =
new DruidDataSource();
druidDataSource.setDriverClassName(driverClassName);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
return druidDataSource;
}
}
测试
//在测试类上加入@RunWith注解,指定Spring的运行器
@RunWith(SpringJUnit4ClassRunner.class)
//配置初始化Spring容器的配置文件(配置类)
@ContextConfiguration(classes = {SpringConfig.class}) //加载配置类
//@ContextConfiguration(locations={"classpath:applicationContext.xml"})//加载配置文件
public class DemoTest {
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test01(){
userService.save();
System.out.println(dataSource);
}
}