Spring4.3.8学习[二]

如果转载文章请注明出处, 谢谢 !
本系列文章是学习完 Spring4.3.8 后的详细整理, 如果有错误请向我指明, 我会及时更正~

Spring4.3.8

Spring4.3.8学习[一]

3.4 依赖注入(DI)

控制反转,我们可以把它看作是一个概念。而依赖注入(Dependency Injection)是控制反转的一种实现方法.
James Shore给出了依赖注入的定义:依赖注入就是将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。

3.4.1 xml 形式

3.4.1.1 使用构造器注入

通过参数顺序, 类型等


    
    
    
    
    
    

3.4.1.2 使用属性 setter 方法

public class Person {
    private String name;
    private int age;
    private String gender;
    private Car car;
    private List list;
    private Set set;
    private Map map;
    private Properties properties;
    private Object[] objects;
     [属性 setter 方法]
}

简单Bean的注入


    
    
    
    

引用其他Bean



    
    

3.4.1.3 装配 list 集合


    
        list1
        
    

3.4.1.4 装配 set


    
        set1
        
    

3.4.1.5 装配 map


    
        
            map1
        
        
            
        
    

3.4.1.5 装配 properties


    
        pp1
        pp2
    

3.4.1.6 装配 Object[]


    
        obj1
        
    

3.4.2 注解 Annotation

注解的注入会在XML之前,因此后者配置将会覆盖前者.

配置bean

3.4.2.1 @Component

@Component是所有受 Spring 管理组件的通用形式,泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Component 不推荐使用。

@Component
public class Person {
}

3.4.2.2@Controller

@Controller对应表现层的Bean,也就是Action, 例:

@Controller
@Scope("prototype")
public class UserAction {
}

3.4.2.3 @Respository

用于标注数据访问组件,即DAO组件

@Repository
public class UserDao {
} 

3.4.2.4 @Service

用于标注业务层组件

@Service
public class UserServiceImpl {
}


对于扫描到的组件, Spring有默认的命名策略 :
1)使用非限定类名,第一个字母小写
(UserServiceImpl -> userServiceImpl)

2)在注解中通过 value 属性值标识组件的名称
(通常可以将UserServiceImpl -> userService,可以将Impl拿掉,这是一个习惯)

@Service("userService")
public class UserServiceImpl {
}

(3)当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.

配置 bean 的属性

3.4.2.5 @Autowired

使用@Autowired 注解自动装配, @Autowired 默认按类型装配.

可以在普通setter方法上使用@Autowired注解

public class UserServiceImpl implements UserService{
    private UserDao userDao;

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

可以将注解应用到构造器和字段上

public class UserServiceImpl implements UserService{
    private UserDao userDao;

    @Autowired
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }
}
public class UserServiceImpl implements UserService{
    @Autowired
    private UserDao userDao;
}

可以将注解应用到任意名称或参数的方法上

public class UserServiceImpl implements UserService{
    private UserCatalog userCatalog;
    private UserDao userDao;
    
    @Autowired
    public void prepare(UserCatalog catalog, UserDao dao){
        this.userCatalog = catalog;
        this.userDao = dao;
    }

可以把指定类型的所有Bean提供给一个数组类型, 集合类型的变量

public class UserServiceImpl implements UserService{
    @Autowired
    private UserCatalog[] catalogs;
}

xml 中只定义了几个 对应bean




@Autowired注解是按类型装配依赖对象,默认情况下它要求依赖对象必须存在,一旦找不到对应的Bean,自动注入就会失败。若要改变默认的策略或允许null值,可以设置它required属性为false。

public class UserServiceImpl implements UserService{
      // xml 中没有定义UserFinder的 bean
    @Autowired(required = false)
    private UserFinder userFinder;
}

3.4.2.6 @Qualifier

使用@Qualifier调整基于注解的自动注入.
在指定参数上使用@Qualifier,可以缩小类型匹配的范围,更容易为参数找到指定的Bean。
[想使用按名称装配,可以结合@Qualifier注解一起使用]

public class UserServiceImpl implements UserService{
    @Qualifier("userD")
    @Autowired
    private UserDao userD;
}

对应的Bean定义如下所示。
标识值为“userDe”的Bean将会被标记为@Qualifier(“userDe”)的参数所注入:


    

如果全部使用注解, 可以在UserDaoImpl中使用Repository配置

@Repository("userDe")
public class UserDaoImpl implements UserDao{
}

3.4.2.7 @Resource

@Resource 注解和@Autowired一样,也可以标注在字段或属性的setter方法上.

@Resource注解默认按名称装配。

名称可以通过@Resource的name属性指定,如果没有指定name属性,
当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象;
当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。

public class UserServiceImpl implements UserService{
    @Qualifier("userD")
    @Autowired
    private UserDao userD;

    @Resource(name = "daoU")
    private UserDao userDao;
}

注: 如果没有指定name属性,并且按照默认的名称找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。

3.4.2.8 @Required

@Required注解应用于Bean属性的setter方法,如下:

public class UserServiceImpl implements UserService{
    private UserDao userDao;
    @Required
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

这个表明Bean的属性值必须在配置中指定,可以通过显示的在Bean定义中指定,也可以使用自动注入。若没有为这个属性指定值,那么容器会抛出一个异常。


    


3.4.2.8 @PostConstruct & @PreDestroy

生命周期注解
之前的做法是在xml中定义init-method 和 destroy-method方法

public class User {
    public User() {
        System.out.println("user .. 构造函数");
    }
    @PostConstruct
    public void  init(){
        System.out.println("I'm  init  method  using  @PostConstrut....");
    }

    @PreDestroy
    public void  destroy(){
        System.out.println("I'm  destory method  using  @PreDestroy.....");
    }
}

3.5 扫描

spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理.

它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

  1. 引入context命名空间 需要在xml配置文件中配置以下信息
  2. 在配置文件中添加context:component-scan标签


        
    
    

在 base-package 指明一个包, 表明自动扫描目录 com.lanou 包及其子包中的注解,当需要扫描多个包时, 可以使用逗号分隔.
其他用法:


 




    




    




    




    

3.6 Spring 的继承

public class People {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}


public class Student extends People {

}

    


public void testExtents(){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) context.getBean("student");
// student 打印出来的名字为 null  
 System.out.println(student.getName());
}

配置文件需要更改



    


还有其他方式解决 student 的名字赋值问题么?
student 也继承了 people 的 name setter 方法

Spring4.3.8学习[三]
Spring4.3.8学习之 与 Struts2 整合[四]
Spring4.3.8学习之与Hibernate4 整合[五]
Spring4.3.8学习之S2SH 整合[六]

你可能感兴趣的:(Spring4.3.8学习[二])