1. Trang chủ >
  2. Công Nghệ Thông Tin >
  3. Kỹ thuật lập trình >

3-5. Checking Properties with Dependency Checking

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (5.49 MB, 753 trang )


9799ch03.qxd



56



5/5/08



4:50 PM



Page 56



CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING



Table 3-1. Dependency Checking Modes Supported by Spring



Mode



Description



none*



No dependency checking will be performed. Any properties can be left unset.



simple



If any properties of the simple types (the primitive and collection types) have not been

set, an UnsatisfiedDependencyException will be thrown.



objects



If any properties of the object types (other than the simple types) have not been set, an

UnsatisfiedDependencyException will be thrown.



all



If any properties of any type have not been set, an UnsatisfiedDependencyException

will be thrown.



* The default mode is none, but this can be changed by setting the default-dependency-check attribute of the

root element. This default mode will be overridden by a bean’s own mode if specified. You must set

this attribute with great care as it will alter the default dependency checking mode for all the beans in the

IoC container.



How It Works

Checking Properties of the Simple Types

Suppose the suffix property was not set for the sequence generator. Then the generator

would generate sequence numbers whose suffix was the string null. This kind of issue is often

very hard to debug, especially in a complicated bean. Fortunately, Spring is able to check if all

properties of certain types have been set. To ask Spring to check properties of the simple types

(i.e., the primitive and collection types), set the dependency-check attribute of to

simple.


class="com.apress.springrecipes.sequence.SequenceGenerator"

dependency-check="simple">







If any properties of such types have not been set, an UnsatisfiedDependencyException will

be thrown, indicating the unset property.

Exception in thread "main"

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating

bean with name 'sequenceGenerator' defined in class path resource [beans.xml]:

Unsatisfied dependency expressed through bean property 'suffix': Set this property

value or disable dependency checking for this bean.



9799ch03.qxd



5/5/08



4:50 PM



Page 57



CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING



Checking Properties of the Object Types

If the prefix generator is not set, then the evil NullPointerException will be thrown when prefix generation is requested. To enable dependency checking for bean properties of object

types, (i.e., other than simple types), change the dependency-check attribute to objects.


class="com.apress.springrecipes.sequence.SequenceGenerator"

dependency-check="objects">







Then when you run the application, Spring will notify you that the prefixGenerator property has not been set.

Exception in thread "main"

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating

bean with name 'sequenceGenerator' defined in class path resource [beans.xml]:

Unsatisfied dependency expressed through bean property 'prefixGenerator': Set this

property value or disable dependency checking for this bean.



Checking Properties of All Types

If you would like to check all bean properties whatever the type is, you can change the

dependency-check attribute to all.


class="com.apress.springrecipes.sequence.SequenceGenerator"

dependency-check="all">







Dependency Checking and Constructor Injection

Spring’s dependency checking feature will only check if a property has been injected via the

setter method. So, even if you have injected the prefix generator via a constructor, an

UnsatisfiedDependencyException will still be thrown.


class="com.apress.springrecipes.sequence.SequenceGenerator"

dependency-check="all">











57



9799ch03.qxd



58



5/5/08



4:50 PM



Page 58



CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING



3-6. Checking Properties with the @Required Annotation

Problem

Spring’s dependency checking feature can only check for all properties of certain types. It’s not

flexible enough to check for particular properties only. In most cases, you would like to check

if particular properties have been set, but not all properties of certain types.



Solution

RequiredAnnotationBeanPostProcessor is a Spring bean post processor that checks if all the

bean properties with the @Required annotation have been set. A bean post processor is a special kind of Spring bean that is able to perform additional tasks on each bean before its

initialization. To enable this bean post processor for property checking, you must register it

in the Spring IoC container. Note that this processor can only check if the properties have

been set, but can’t check if their value is not null.



How It Works

Suppose that both the prefixGenerator and suffix properties are required for a sequence

generator. You can annotate their setter methods with @Required.

package com.apress.springrecipes.sequence;

import org.springframework.beans.factory.annotation.Required;

public class SequenceGenerator {

private PrefixGenerator prefixGenerator;

private String suffix;

...

@Required

public void setPrefixGenerator(PrefixGenerator prefixGenerator) {

this.prefixGenerator = prefixGenerator;

}

@Required

public void setSuffix(String suffix) {

this.suffix = suffix;

}

...

}

To ask Spring to check if these properties have been set on all sequence generator

instances, you have to register a RequiredAnnotationBeanPostProcessor instance in the IoC

container. If you are using a bean factory, you have to register this bean post processor

through the API. Otherwise, you can just declare an instance of this bean post processor in

your application context.



9799ch03.qxd



5/5/08



4:50 PM



Page 59



CHAPTER 3 ■ BEAN CONFIGURATION IN SPRING





If you are using Spring 2.5, you can simply include the

element in your bean configuration file, and a RequiredAnnotationBeanPostProcessor instance

will automatically get registered.


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-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd">



...



If any properties with @Required have not been set, a BeanInitializationException will be

thrown by this bean post processor.

Exception in thread "main" org.springframework.beans.factory.BeanCreationException:

Error creating bean with name 'sequenceGenerator' defined in class path resource

[beans.xml]: Initialization of bean failed; nested exception is

org.springframework.beans.factory.BeanInitializationException: Property

'prefixGenerator' is required for bean 'sequenceGenerator'

In addition to the @Required annotation, RequiredAnnotationBeanPostProcessor can also

check the properties with your custom annotation. For example, you can create the following

annotation type:

package com.apress.springrecipes.sequence;

...

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface Mandatory {

}

And then you can apply this annotation to the setter methods of the required properties.

package com.apress.springrecipes.sequence;

public class SequenceGenerator {

private PrefixGenerator prefixGenerator;

private String suffix;

...

@Mandatory



59



Xem Thêm
Tải bản đầy đủ (.pdf) (753 trang)

×