Spring5-Annotation
# Spring5-Annotation
# 1. 注解实现Bean依赖注入
注解实现Bean配置主要用来进行如依赖注入、生命周期回调方法定义等,不能消除XML文件中的Bean元数据定义,且基于XML配置中的依赖注入的数据将覆盖基于注解配置中的依赖注入的数据。
Spring3开始支持的基于注解实现Bean依赖注入支持如下注解:
- Spring自带依赖注入注解: Spring自带的一套依赖注入注解;
- JSR-250注解:Java平台的公共注解,是Java EE 5规范之一,在JDK6中默认包含这些注解,从Spring2.5开始支持。JCP:Java Community Process是由多个厂家出人来构成的J2EE组织,主要是用于定Java的一些新的标准
- 而每一个标签都可以称之为一个JSR(Java Specification Requests)
- JSR-330注解:Java 依赖注入标准,Java EE 6规范之一,可能在加入到未来JDK版本,从Spring3开始支持;
- JPA注解:用于注入持久化上下文和实体管理器。
这三种类型的注解在Spring3中都支持,类似于注解事务支持,想要使用这些注解需要在Spring容器中开启注解驱动支持,即使用如下配置方式开启:
<?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:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 上下文支持注解的形式 -->
<context:annotation-config></context:annotation-config>
</beans>
2
3
4
5
6
7
8
9
10
11
12
13
JSR-250注解
- @Resource:自动装配,,如果指定name属性将根据名字装配,可以使用如下方式来指定:
- @Resource注解应该只用于setter方法注入,不能提供如
@Autowired
多参数方法注入; - @Resource在没有指定name属性的情况下首先将根据setter方法对应的字段名查找资源,如果找不到再根据类型查找;
- @Resource首先将从JNDI环境中查找资源,如果没找到默认再到Spring容器中查找,因此如果JNDI环境中有和Spring容器同名的资源时需要注意。
- @PostConstruct和@PreDestroy:通过注解指定初始化和销毁方法定义
# 1.1.1 Spring自带的@Component注解及扩展: 组件
- 在类上使用@Component注解,表示该类定义为Spring管理Bean,使用默认value(可选)属性表示Bean标识符。
- @Repository:
@Component
扩展,被@Repository
注解的POJO类表示DAO层实现,从而见到该注解就想到DAO层实现,使用方式和@Component
相同; - @Service:
@Component
扩展,被@Service
注解的POJO类表示Service层实现,从而见到该注解就想到Service层实现,使用方式和@Component
相同; - @Controller:
@Component
扩展,被@Controller
注解的类表示Web层实现,从而见到该注解就想到Web层实现,使用方式和@Component
相同;放在Action前.
注解对应的jar包
1、@Autowired org.springframework.beans.factory.annotation.Autowired;
2、@Qualifier org.springframework.beans.factory.annotation.Qualifier;
3、@Component org.springframework.stereotype.Component;
4、@Resource javax.annotation.Resource;
5、@Scope org.springframework.context.annotation.Scope;
6、@PostConstruct javax.annotation.PreDestroy;
7、@PreDestroy javax.annotation.PreDestroy;
# 2. @Autowired和@Resource区别
- 所在包的不同
@Resource -> javax.annotation.Resource
@Autowired -> org,springframework.beans.factory.annotation.Autowired
@Resource
默认是按照name来装配的,如果没有name,再按照类型装配;而@Autowired
默认使用的是类型装配,如果使用指定名字需要配合Qualifier
@Component
public class BookManager{
//@Resource //filed的注入操作
//@Autowired //默认根据类型来注入的
@Autowired
@Qualifier(value="book")
private Book book;
}
2
3
4
5
6
7
8
多实例:原型的方式创建对象
@Component(value="u")
//多实例
@Scope(value="prototype")
public class Users implements Serializable{
}
2
3
4
5
6
# 3. 操作步骤
- 将之前的
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:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 上下文支持注解的形式 -->
<context:annotation-config></context:annotation-config>
</beans>
2
3
4
5
6
7
8
9
10
11
12
这样当spring加载配置文件时,发现<context:annotation-config/>
标签后,会加载以下四个类(用于处理annotation方式的配置)
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- PersistenceAnnotationBeanPostProcessor
- RequiredAnnotationBeanPostProcessor
- 意味着我们的xml中关于bean的配置信息需要转移到实体类(dao service...)进行配置。配置文件中通常要说明,去哪里找这些信息
<!-- 指定位置 component 组件 scan-->
<context:component-scan base-package="com.etc"></context:component-scan>
2
- 定义一个实体类,同时通过设置其注解表示形式
普通的字面值的注入
package com.etc.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "author")
public class Author {
//@value注入,写在属性前
@Value(value = "1")
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
//@value注入写在setter方法前
@Value(value = "老张")
public void setName(String name) {
this.name = name;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
测试类如下,采用了spring的test和junit测试结合.
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.etc.entity.Author;
//使用springTest 和junit测试结合
//@RunWith 表示的是运行启动类
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration加载配置文件
@ContextConfiguration(locations = {"/applicationContext.xml"})
public class TestAuthor {
//需要一个author对象
//@autowired 默认使用类型啦
//@Autowired
@Resource(name ="author")
private Author author;
@Test
public void getAuthor()
{
System.out.println(author.getId()+","+author.getName());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 4. @Bean说明
Spring的新Java配置支持中的中心工件是@Configuration
注释类和@Bean
注释方法
该@Bean
注释被用于指示一个方法实例,配置和初始化为通过Spring IOC容器进行管理的新对象。对于那些熟悉Spring的<beans/>
XML配置的人来说,@Bean注释
与<bean/>
元素扮演的角色相同。你可以@Bean
在任何Spring中使用annotated
方法 @Component。但是,它们最常用于@Configuration
的bean类。
对类进行注释@Configuration
表明其主要目的是作为bean定义的来源。此外,@Configuration
类允许通过调用@Bean
同一类中的其他方法来定义bean间依赖关系。最简单的@Configuration
类如下:
public class Blog {
private String title;
public Blog(String title) {
super();
this.title = title;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BlogConfig类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 使用注解来完成blogbean的返回
*
* @bean写在一个方法前面
* @Configuration类前
* @author Administrator
*
*/
@Configuration
public class BlogConfig {
@Bean
public Blog blog() {
return new Blog("测试title");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 5. AnnotationConfigApplicationContext
package com.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.etc.entity.Author;
public class TestAuthorAnnotationContext {
@Test
public void getAuthor() {
//参数为可变长度参数,表示的是要扫描的包
ApplicationContext context = new AnnotationConfigApplicationContext("com.etc");
Author author = context.getBean(Author.class);
System.out.println(author.getId() + "," + author.getName());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 6. Dao和Service层进行注入
首先:entity定义了组件@Component,使用@Value注入了字面值:
package com.etc.entity;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component(value = "author")
public class Author {
//@value注入,写在属性前
@Value(value = "1")
private int id;
@Override
public String toString() {
return "Author [id=" + id + ", name=" + name + "]";
}
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
//@value注入写在setter方法前
@Value(value = "老张")
public void setName(String name) {
this.name = name;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Dao的注入:暂时没有连接数据库,所以简单注入一个Author对象
package com.etc.dao;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.etc.entity.Author;
@Repository
public class AuthorDao {
// 有一个属性 author
@Autowired
private Author author;
public List<Author> getAuthors() {
return Arrays.asList(author);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Service中需要调用dao,所以service中注入dao对象:
package com.etc.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.etc.dao.AuthorDao;
import com.etc.entity.Author;
@Service
public class AuthorService {
//注入一个authorDao类型对象
@Autowired
private AuthorDao authordao;
public List<Author> getAuthors()
{
return authordao.getAuthors();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
测试类:
package com.test;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.etc.entity.Author;
import com.etc.service.AuthorService;
//使用springTest 和junit测试结合
//@RunWith 表示的是运行启动类
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration加载配置文件
@ContextConfiguration(locations = { "/applicationContext.xml" })
public class TestAuthor_Service {
// @autowired 默认使用类型啦
@Autowired
private AuthorService authorService;
@Test
public void getAuthor() {
System.out.println(authorService.getAuthors());
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
控制台输出结果
[Author [id=1,name="老张"]]
# 7. SpringAOP的Annotation
如果使用了new AnnotationConfigApplicationContext("com.etc");则不再读取applicationContext.xml中的配置文件,那么之前的:aop的注解支持也无法扫描
此时可以在LogAop的切面类上增加如下注解:@EnableAspectJAutoProxy
//切面类
@Aspect
@Component
@EnableAspectJAutoProxy
public class LogAop{
//具体的方法,前置通知方法
@Before(value="execution(* com.xmvpd.service.impl.BlogServiceImpl.*(..))")
public void before(){
System.out.println("before current:" + System.currentTimeMillis())
}
}
2
3
4
5
6
7
8
9
10
11
使用 @EnableAspectJAutoProxy
用来代替aop:aspectj-autoproxy的节点。