[Spring]注記ベースIoCコンテナ構成

9834 ワード

概要
Spring 2.5は注記を導入した.そこで,注釈方式を用いてJavaBeanに注入することはxml方式を一定に爆発させるのではないかという問題が発生した.必ずしもそうとは限らない.いわゆる、仁者見仁智者見智.何事にも長所と短所があり、あなたがどのように取捨選択するかを見ます.注釈の長所と短所を見てみましょう: :構成を大幅に削減し、構成をより細かくすることができます.クラス、方法、フィールドは注釈でマークすることができます. :注釈を使用すると、侵入プログラミングが避けられず、いくつかの問題も発生します.
  • ソースコードに注釈を追加してコンパイルする必要があります.
  • 注釈は往々にして分散しており、管理しにくい.

  • 注意:springでは、先に注釈注入を行い、xml注入になります.そのため、注入の目標が同じであれば、後者は前者を上書きします.
    注釈の開始
    Springのデフォルトでは注記は使用できません.注記を使用するには、xmlで注記を開始する必要があります.起動方法:xmlにラベルを入れるのは簡単でしょう.
    
    

    注意:は、定義されたコンテキストのみを取得します.どういう意味ですか.つまり、DispatcherServiceletにWebApplicationContextを指定した場合、他のパスはチェックされずにcontrollerで@Autowired注釈のみが検索されます.
    Spring注記
    @Required @Required注記はbeanプロパティを修飾するsetterメソッドにのみ使用できます.影響を受けるbeanプロパティは、構成時にxmlプロファイルに埋め込まれる必要があります.そうしないと、コンテナはBeanInitializationExceptionを放出します.
    public class AnnotationRequired {
        private String name;
        private String sex;
    
        public String getName() {
            return name;
        }
    
        /**
         * @Required     bean   setter       ,    bean            xml     ,
         *                  BeanInitializationException。
         */
        @Required
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    }
    

    @Autowired @Autowired注記は、属性、setterメソッド、構築メソッドを修飾するために使用することができる.
    注意:@Autowired注記は、コンストラクションメソッドを修飾するためにも使用できますが、クラスにデフォルトのコンストラクションメソッドしかない場合は、必要ありません.複数のコンストラクタがある場合は、少なくとも1つを修飾して、コンテナのどちらが使用しなければならないかを教えなければなりません.@Injectの代わりに、JSR 330の注釈@Autowiredを使用することができる.
    public class AnnotationAutowired {
        private static final Logger log = LoggerFactory.getLogger(AnnotationRequired.class);
    
        @Autowired
        private Apple fieldA;
    
        private Banana fieldB;
    
        private Orange fieldC;
    
        public Apple getFieldA() {
            return fieldA;
        }
    
        public void setFieldA(Apple fieldA) {
            this.fieldA = fieldA;
        }
    
        public Banana getFieldB() {
            return fieldB;
        }
    
        @Autowired
        public void setFieldB(Banana fieldB) {
            this.fieldB = fieldB;
        }
    
        public Orange getFieldC() {
            return fieldC;
        }
    
        public void setFieldC(Orange fieldC) {
            this.fieldC = fieldC;
        }
    
        public AnnotationAutowired() {}
    
        @Autowired
        public AnnotationAutowired(Orange fieldC) {
            this.fieldC = fieldC;
        }
    
        public static void main(String[] args) throws Exception {
            AbstractApplicationContext ctx =
                            new ClassPathXmlApplicationContext("spring/spring-annotation.xml");
    
            AnnotationAutowired annotationAutowired =
                            (AnnotationAutowired) ctx.getBean("annotationAutowired");
            log.debug("fieldA: {}, fieldB:{}, fieldC:{}", annotationAutowired.getFieldA().getName(),
                            annotationAutowired.getFieldB().getName(),
                            annotationAutowired.getFieldC().getName());
            ctx.close();
        }
    }
    

    xmlでの構成
    
    
    
    
    
    

    @Qualifier @Autowired注記では,複数の候補のbeanが修飾タイプに合致していることが発見されるとSpringは盲目になると述べた.
    では、この問題をどう解決するか.@Qualifierでbean名を指定することで、本当に必要なbeanをロックすることができます.
    public class AnnotationQualifier {
        private static final Logger log = LoggerFactory.getLogger(AnnotationQualifier.class);
    
        @Autowired
        @Qualifier("dog") /**     ,     */
        Animal dog;
    
        Animal cat;
    
        public Animal getDog() {
            return dog;
        }
    
        public void setDog(Animal dog) {
            this.dog = dog;
        }
    
        public Animal getCat() {
            return cat;
        }
    
        @Autowired
        public void setCat(@Qualifier("cat") Animal cat) {
            this.cat = cat;
        }
    
        public static void main(String[] args) throws Exception {
            AbstractApplicationContext ctx =
                    new ClassPathXmlApplicationContext("spring/spring-annotation.xml");
    
            AnnotationQualifier annotationQualifier =
                    (AnnotationQualifier) ctx.getBean("annotationQualifier");
    
            log.debug("Dog name: {}", annotationQualifier.getDog().getName());
            log.debug("Cat name: {}", annotationQualifier.getCat().getName());
            ctx.close();
        }
    }
    
    abstract class Animal {
        public String getName() {
            return null;
        }
    }
    
    class Dog extends Animal {
        public String getName() {
            return " ";
        }
    }
    
    class Cat extends Animal {
        public String getName() {
            return " ";
        }
    }
    

    xmlでの構成
    
    
    
    
    

    JSR 250注記
    @Resource
    SpringはJSP 250に規定された注釈@Resourceをサポートする.この注記は指定した名前に基づいてbeanを注入します.@Resourceに名前が指定されていない場合は、@Autowiredのようにタイプ別に一致を探します.
    Springでは、CommonAnnotationBeanPostProcessorによって@Resource注釈が処理される.
    public class AnnotationResource {
        private static final Logger log = LoggerFactory.getLogger(AnnotationResource.class);
    
        @Resource(name = "flower")
        Plant flower;
    
        @Resource(name = "tree")
        Plant tree;
    
        public Plant getFlower() {
            return flower;
        }
    
        public void setFlower(Plant flower) {
            this.flower = flower;
        }
    
        public Plant getTree() {
            return tree;
        }
    
        public void setTree(Plant tree) {
            this.tree = tree;
        }
    
        public static void main(String[] args) throws Exception {
            AbstractApplicationContext ctx =
                            new ClassPathXmlApplicationContext("spring/spring-annotation.xml");
    
            AnnotationResource annotationResource =
                            (AnnotationResource) ctx.getBean("annotationResource");
            log.debug("type: {}, name: {}", annotationResource.getFlower().getClass(), annotationResource.getFlower().getName());
            log.debug("type: {}, name: {}", annotationResource.getTree().getClass(), annotationResource.getTree().getName());
            ctx.close();
        }
    }
    

    xmlの構成
    
    
    
    
    

    @PostConstructと@PreDestroy@PostConstructおよび@PreDestroyは、JSR 250によって規定されたライフサイクルの注釈である.
    名前から分かるように、1つは構築後に呼び出される方法であり、1つは破棄前に呼び出される方法である.
    public class AnnotationPostConstructAndPreDestroy {
        private static final Logger log = LoggerFactory.getLogger(AnnotationPostConstructAndPreDestroy.class);
    
        @PostConstruct
        public void init() {
            log.debug("call @PostConstruct method");
        }
    
        @PreDestroy
        public void destroy() {
            log.debug("call @PreDestroy method");
        }
    }
    

    JSR 330注記
    Spring 3.0から、SpringはJSR 330標準注釈(依存注入)をサポートする.
    注意:JSR 330注釈を使用する場合は、外部jarパッケージを使用する必要があります.
    mavenを使用してjarパッケージを管理する場合は、pom.xmlに依存するものを追加するだけです.
    
      javax.inject
      javax.inject
      1
    
    

    @Inject @Injectは、@Autowiredと同様に、属性、setterメソッド、構造メソッドを修飾することができる.
    public class AnnotationInject {
        private static final Logger log = LoggerFactory.getLogger(AnnotationInject.class);
        @Inject
        Apple fieldA;
    
        Banana fieldB;
    
        Orange fieldC;
    
        public Apple getFieldA() {
            return fieldA;
        }
    
        public void setFieldA(Apple fieldA) {
            this.fieldA = fieldA;
        }
    
        public Banana getFieldB() {
            return fieldB;
        }
    
        @Inject
        public void setFieldB(Banana fieldB) {
            this.fieldB = fieldB;
        }
    
        public Orange getFieldC() {
            return fieldC;
        }
    
        public AnnotationInject() {}
    
        @Inject
        public AnnotationInject(Orange fieldC) {
            this.fieldC = fieldC;
        }
    
        public static void main(String[] args) throws Exception {
            AbstractApplicationContext ctx =
                            new ClassPathXmlApplicationContext("spring/spring-annotation.xml");
            AnnotationInject annotationInject = (AnnotationInject) ctx.getBean("annotationInject");
    
            log.debug("type: {}, name: {}", annotationInject.getFieldA().getClass(),
                            annotationInject.getFieldA().getName());
    
            log.debug("type: {}, name: {}", annotationInject.getFieldB().getClass(),
                            annotationInject.getFieldB().getName());
    
            log.debug("type: {}, name: {}", annotationInject.getFieldC().getClass(),
                            annotationInject.getFieldC().getName());
    
            ctx.close();
        }
    }