cccreator / Java

Accumulation And Mark
0 stars 0 forks source link

SpringMVC 注解的使用_2 #5

Open cccreator opened 6 years ago

cccreator commented 6 years ago

@Autowired注解

@Autowired注释可以对类的成员变量、方法及构造函数进行标注,自动完成装配工作。通过@Autowired来消除set,get方法。使用时@Autowired(required = false)

在使用@Autowired注解之前,我们需要在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
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">

    <context:annotation-config/>

</beans>

其中<context:annotation-config/>这个配置隐式注册了多个对注解进行解析处理的处理器:

  AutowiredAnnotationBeanPostProcessor
    CommonAnnotationBeanPostProcessor
    PersistenceAnnotationBeanPostProcessor
    RequiredAnnotationBeanPostProcessor

注册这4个BeanPostProcessor的作用就是为了你的系统能够识别响应的注解。

例如:

一般来说,这些注解我们还是比较常用,尤其是Antowired的注解,在自动注入的时候更是经常使用,所以如果总是需要按照传统的方式一条一条配置显得有些繁琐和没有必要,于是spring给我们提供<context:annotation-config/>的简化配置方式,自动帮你完成声明。 不过,我们使用注解一般都会配置扫描包路径选项<context:component-scan base-package=”XX.XX”/> 该配置项其实也包含了自动注入上述processor的功能,因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除了。比如: <context:component-scan base-package="carPoolingController, carPoolingService, carPoolingDao" /> 就把controller包下 service包下 dao包下的注解全部扫描了 修改以上配置文件的头信息后,我们就可以在Java代码通过注解方式来注入bean,看下面代码

  1. @Resource

    public class StudentService3 implements IStudentService {
    //@Resource(name="studentDao")放在此处也是可行的
    private IStudentDao studentDao;
    
    private String id;
    
    public void setId(String id) {
    this.id = id;
    }
    @Resource(name = "studentDao")//通过此注解完成从spring配置文件中查找名称为studentDao的bean来装配字段studentDao,如果spring配置文件中不存在studentDao名称的bean,则转向按照bean类型进行查找
    public void setStudentDao(IStudentDao studentDao) {
        this.studentDao = studentDao;
    }
    public void saveStudent() {
        studentDao.saveStudent();
        System.out.print(",ID 为:"+id);
    }
    }

    配置文件添加如下信息:

    
    <bean id="studentDao" class="com.wch.dao.impl.StudentDao">
    </bean>

2. @Autowired

public class StudentService3 implements IStudentService { //@Autowired放在此处也是可行的 private IStudentDao studentDao;

private String id;

public void setId(String id) { this.id = id; } @Autowired//通过此注解完成从spring配置文件中 查找满足studentDao类型的bean//@Qualifier("studentDao")则按照名称经行来查找转配的 public void setStudentDao(IStudentDao studentDao) { this.studentDao = studentDao; }

public void saveStudent() { studentDao.saveStudent(); System.out.print(",ID 为:"+id); } }

<bean id="studentDao" class="com.wch.dao.impl.StudentDao"></bean>
<bean id="studentService3" class="com.wch.service.impl.StudentService3" />

配置文件添加如下配置信息

- 在java代码中可以使用@Autowire或者@Resource注解方式进行装配,这两个注解的区别是:@Autowire
 默认按照类型装配,默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,如果我们想使用按照名称装配,可 以结合@Qualifier注解一起使用;

- @Resource默认按照名称装配,当找不到与名称匹配的bean才会按照类型装配,可以通过name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找 依赖对象.注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖的对象时候,会回退到按照类型装配,但一旦指定了name属性,就只能按照名称 装配了.

**差异性补充**
- 他们的主要区别就是@Autowired是默认按照类型装配的 @Resource默认是按照名称装配的
byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。
byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配

**整个过程的分析**

- 分析整个过程
        1、当启动spring容器的时候,spring容器加载了配置文件
        2、在spring配置文件中,只要遇到bean的配置,就会为该bean创建对象
        3、在纳入spring容器的范围内查找所有的bean,看哪些bean的属性或者方法上加有@Resource
        4、找到@Resource注解以后,判断该注解name的属性是否为""(name没有写)
              如果没有写name属性,则会让属性的名称的值和spring中ID的值做匹配,如果匹配成功则赋值
                                        如果匹配不成功,则会按照类型进行匹配,如果匹配不成功,则报错
              如果有name属性,则会按照name属性的值和spring的bean中ID进行匹配,匹配成功,则赋值,不成功则报错

### @Autowired的三种使用方式
1. 通过构造器注入,如:

private JdbcTemplate JdbcTemplate; @Autowired public LoginContriller (JdbcTemplate JdbcTemplate){ this.jdbcTemplate=jdbcTemplate }

2. 通过setter方法注入,如

private JdbcTemplate JdbcTemplate; @Autowired public void setjdbcTemplate(JdbcTemplate JdbcTemplate){ this.jdbcTemplate=jdbcTemplate }

3. 通过field反射注入

@Autowired private JdbcTemplate JdbcTemplate;



> Spring3.0建议使用setter注入覆盖构造器注入;Spring4.0建议使用构造器注入;如果注入的属性是必选的属性,使用构造器注入;如果注入的属性是可选的,使用setter方法注入;
cccreator commented 6 years ago

@Override注解

@Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处: 1、可以当注释用,方便阅读; 2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

举例:在重写父类的onCreate时,在方法前面加上@Override 系统可以帮你检查方法的正确性。 @Override public void onCreate(Bundle savedInstanceState)

{…….} 这种写法是正确的,如果你写成:

@Override public void oncreate(Bundle savedInstanceState) {…….} 编译器会报如下错误:The method oncreate(Bundle) of type HelloWorld must override or implement a supertype method,以确保你正确重写onCreate方法(因为oncreate应该为onCreate)。而如果你不加@Override,则编译器将不会检测出错误,而是会认为你为子类定义了一个新方法:oncreate

cccreator commented 6 years ago

@Service注解-Resource注解

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("xxx")
public class ItemsServiceImpl implements ItemsService {

    @Autowired
    private ItemsMapper itemsMapper;
}
public class ItemsController {

    @Resourse(“xxx”)
    private ItemsService itemsService;
}