1.为什么要使用Spring注解?
传统的Spring做法是使用.xml文件来对bean对象进行注入。
会导致的问题:
(1)如果所有的内容都配置在.xml文件中,那么.xml文件会十分庞大,配置文件的可读性和可维护性变得很低。
(2)如果在开发过程中.java文件和.xml文件之间不断来回切换,是一件麻烦的事情,开发效率降低。
为了解决这两个问题,Spring引入注解,通过“@xxx”的方式,让注解和Java Bean 紧密结合。大大减少配置文件,又增加了Java Bean的可读性和内聚性。
Java Bean是一个遵循特定写法的Java类。
具有的特点:
(1)这个Java类必须有一个无参的构造函数
(2)属性必须私有化
(3)提供getter和setter方法
(4)实现serializable接口
2.注解的使用
1.导包或者是添加依赖包(maven)
2.需要在配置文件中添加一个约束:contenxt
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
3.配置扫描组件
<!--自动扫描包下的注解-->
<context:component-scan base-package="com.msj.pojo"/>
4.JavaBean类(User.java)
在User类上面添加一个注解@Controller
package demo05.com.msj;
import org.springframework.stereotype.Controller;
@Controller("users")
public class User {
private String username = "www";
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
5.测试
public class Test05 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/com/msj/bean05.xml");
User users = (User)context.getBean("users");
System.out.println(users.getUsername());
}
}
3.IOC注入
1.可以不用提供set方法,直接在属性名上添加一个@Value
2.有set方法可以直接在set方法上面加上@Value,这样也可以把值注入
@Controller("users")
public class User {
//在属性上添加 @Value,可以不用添加set方法
@Value("eee")
private String username;
private Integer age;
public String getUsername() {
return username;
}
// public void setUsername(String username) {
// this.username = username;
// }
public Integer getAge() {
return age;
}
//在set方法上面加上 @Value
@Value("23")
public void setAge(Integer age) {
this.age = age;
}
}
4.常用注解
Spring部分
1. 声明bean的注解
(1)@Component 组件,没有明确的角色
(2)@Service 在业务逻辑层使用(Service层)
(3)@Repository 在数据访问层使用 (Dao层)
(4)@Controller 控制器的声明
2. 注入bean的注解
(1)@Autowired
(2)@Resource(jdk的注解)
都可以注解在set方法和属性上,推荐注解在属性上
- 共同点
两种都可以写在字段和setter方法上,两者如果都写在字段上 ,那么就不需要再写在setter方法上 - 不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
该注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。
public class TestServiceImpl {
// 下面两种@Autowired只要使用一种即可
@Autowired
private UserDao userDao; // 用于字段上
@Autowired
public void setUserDao(UserDao userDao) { // 用于属性的方法上
this.userDao = userDao;
}
}
如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
public class TestServiceImpl {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
(2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。
@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
public class TestServiceImpl {
// 下面两种@Resource只要使用一种即可
@Resource(name="userDao")
private UserDao userDao; // 用于字段上
@Resource(name="userDao")
public void setUserDao(UserDao userDao) { // 用于属性的setter方法上
this.userDao = userDao;
}
}
- 总结
(1)当一个接口只有一个实现类,推荐使用@Autowired,默认byType注入,不一定 真的byType,可以修改为byName。
(2)当一个接口有多个实现类,推荐使用@Resource,默认byName注入。
3. java配置类相关的注解
(1)@Configuration 声明当前类为配置类,相当于xml形式的Spring配置(类上)
@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法。
(2)@Bean 注解在方法上,声明当前方法的返回值为一个bean,替代xml中的方式(方法上)
User.java
public class User {
//在属性上添加@Value,可以不用添加set方法
private String username;
private Integer age;
public String getUsername() {
return username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
AppConfig.java 配置类,替代.xml文件
@Configuration
public class AppConfig {
@Bean("u")
public User user(){
User user = new User();
user.setUsername("ccc");
user.setAge(12);
return user;
}
}
测试类
使用AnnotationConfigApplicationContext
public class Test05 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
User user = (User)context.getBean("u");
System.out.println(user.getUsername()+"--"+user.getAge());
}
}
其中,AppConfig.java替代了bean.xml
<bean id="users" class="demo05.com.msj.User">
<property name="username" value="ddd"/>
<property name="age" value="11"/>
</bean>
(3)@Configuration 声明当前类为配置类,其中内部组合了@Component注解,表明这个类是一个bean(类上)
(4)@ComponentScan 用于对Component进行扫描,相当于xml中的(类上)
ComponentScan做的事情就是告诉Spring从哪里找到bean。
4. 切面(AOP)相关的注解
(1)@Aspect 声明一个切面(类上)
(2)@After 在方法执行之后执行(方法上)
(3)@Before 在方法执行之前执行(方法上)
(4)@Around 在方法执行之前与之后执行(方法上)
(5)@PointCut 声明切点
5. Bean属性的支持
@Scope 设置Spring容器如何新建Bean实例(方法上,得有@Bean)
其设置类型包括:
(1)Singleton (单例,一个Spring容器中只有一个bean实例,默认模式),
(2)Protetype (每次调用新建一个bean),
(3)Request (web项目中,给每个http request新建一个bean),
(4)Session (web项目中,给每个http session新建一个bean)
6. @Value
@Value 为属性注入值(属性上)
7. 环境切换
(1)@Profile 通过设定Environment的ActiveProfiles来设定当前context需要使用的配置环境。(类或方法上)
8. @Qualifier 和 @Primary
当两个实现类实现了同一个接口,并且这两个实现类都被spring IoC容器所管理。那么在我们使用@Autowired注解该bean时候,spring如何知道开发者是要注入哪个bean呢?
(1)@Qualifier
@Qualifier指定需要注入的bean(该注解跟随在@Autowired后),灵活性强。
(2)@Primary
当优先使用哪个bean时,在该实现类上加上此注解。(该注解加在各个bean上)
SpringMVC部分
(1)@Controller 声明该类为SpringMVC中的Controller
(2)@RequestMapping 用于映射Web请求,包括访问路径和参数(类或方法上)
@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法。
(3)@ResponseBody 支持将返回值放在response内,而不是一个页面,通常用户返回json数据(返回值旁或方法上)
(4)@RequestBody 允许request的参数在request体中,而不是在直接连接在地址后面。(放在参数前)
(5)@PathVariable 用于接收路径参数,比如
(6)@RestController 该注解为一个组合注解,相当于@Controller和@ResponseBody的组合,注解在类上,意味着,该Controller的所有方法都默认加上了@ResponseBody。