Maison  >  Article  >  Java  >  Explication détaillée des exemples de code d'utilisation des annotations du framework Spring

Explication détaillée des exemples de code d'utilisation des annotations du framework Spring

黄舟
黄舟original
2017-03-18 10:36:251871parcourir

Écrit devant :

Comme nous le savons tous, dans le framework de développement JavaEE, le framework Spring est le plus utilisé, et le positionnement des annotations dans le framework devient de plus en plus plus évident. Faisons une blague : si cela peut être résolu avec une seule annotation, il ne sera jamais résolu avec un tas de configuration et de code ; s'il ne peut pas être résolu, alors utilisez deux annotations (Attendez, ne pulvérisez pas...)

1.@Component est une annotation générale définie par Spring et peut annoter n'importe quel bean.

2. @Scope définit la portée du bean. Sa portée par défaut est "singleton". De plus, il existe un prototype, une requête, une session et une session globale.

Cas : analyse d'utilisation de @Component et @Scope :

Classe BeanAnnotation :

@Scope
@Component
public class BeanAnnotation {

    public void say(String arg) {
        System.out.println("BeanAnnotation : " + arg);
    }

    public void myHashCode() {
        System.out.println("BeanAnnotation : " + this.hashCode());
    }

}

classe de test junit4→Classe TestBeanAnnotation :

@RunWith(BlockJUnit4ClassRunner.class)
public class TestBeanAnnotation extends UnitTestBase {

    public TestBeanAnnotation() {
        super("classpath*:spring-beanannotation.xml");
    }

    @Test
    public void testSay() {
        BeanAnnotation bean = super.getBean("beanAnnotation");
        bean.say("This is test.");
    }

    @Test
    public void testScpoe() {
        BeanAnnotation bean = super.getBean("beanAnnotation");
        bean.myHashCode();
        bean = super.getBean("beanAnnotation");
        bean.myHashCode();
    }

}

SpringFichier de configuration→spring-beanannotation.xml :

<context:component-scan base-package="com.beanannotation"></context:component-scan>

Analysons d'abord le fichier de configuration Spring , base-package="com.beanannotation" indique que nous traitons uniquement les annotations sous ce nom de package.

Ensuite, analysez la classe BeanAnnotation et il existe une méthode say. En supposant que nous ne savons pas de quel type de classe il s'agit (note : Service ou DAO), nous pouvons utiliser une annotation générale @Component.

Enfin, analysez la classe TestBeanAnnotation. Dans la méthode testSay, super.getBean("beanAnnotation") récupère le bean du conteneur IOC et appelle la méthode say du bean.

Il est temps de poser une question. Lorsque nous super.getBean, nous l'obtenons du conteneur IOC via l'identifiant du bean. Alors, quel est cet identifiant ? Parce que lorsque nous ajoutons @Component à la classe BeanAnnotation, l'identifiant par défaut est beanAnnotation. Si le nom de @Component est spécifié, par exemple, lorsqu'il est spécifié comme @Component(”bean”), lors de test unitaire , l'identifiant obtenu par super.getBean doit lui correspondre pour que le test réussisse.

Ici, je sépare l'annotation @Scope pour l'analyse. Il existe une méthode testScpoe dans la classe TestBeanAnnotation. Il existe une méthode myHashCode dans la classe BeanAnnotation. Vous êtes peut-être un peu confus, pourquoi utiliser this.hashCode() ? Étant donné que @Scope spécifie la portée du bean, afin de garantir que les résultats de la classe de test sont précis et clairs, la valeur du code de hachage est utilisée pour déterminer s'il s'agit du même objet .

3.@Repository, @Service et @Controller sont des annotations plus ciblées.

PS : Ici, il faut comprendre que ces trois annotations sont basées sur les annotations définies par @Component :

①, @Repository est généralement utilisé pour annotez les classes DAO , ce que nous appelons souvent la couche de persistance.
②. @Service est généralement utilisé pour annoter la classe Service, qui est la couche de service.
③. @Controller est généralement utilisé dans la classe Controller, qui est la couche de contrôle (MVC).

4. @Autowired est compris comme la méthode de définition "traditionnelle", qui peut être utilisée dans les méthodes de définition, les constructeurs ou les variables membres, et peut effectuer un assemblage automatique de Spring Beans.

Cas : Analyse d'utilisation @Autowired 1 :

Fichier de configuration Spring → spring-beanannotation.xml :

<context:component-scan base-package="com.beanannotation"></context:component-scan>

SimpleMovieListeclasse :

public class SimpleMovieLister {

    private MovieFinder movieFinder;

    @Autowired(required=false)
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }

}

Par défaut, si aucun bean approprié n'est trouvé, l'autowiring échouera lancera une exception , nous pouvons annoter @Autowired sur cette méthode définie et marquez require=false pour éviter cela. Cependant, cela n'est pas nécessaire. Si l'instance de movieFinder est introuvable, aucune exception ne sera levée. Ce n'est que lors de son utilisation que movieFinder est null. en l'utilisant, déterminez d'abord si movieFinder est nul. Si tel est le cas, une exception de pointeur nul sera signalée.

Il convient de noter que nous savons que chaque classe peut avoir plusieurs constructeurs, mais lors de l'utilisation de @Autowired, il n'y a et ne peut y avoir qu'un seul constructeur qui peut être marqué comme requis = vrai (Remarque : obligatoire La valeur par défaut est faux).

Cas : analyse d'utilisation @Autowired deux :

Classe BeanImplOne :

@Order
@Component
public class BeanImplOne implements BeanInterface {

}

Classe BeanImplTwo :

@Order
@Component
public class BeanImplTwo implements BeanInterface {

}

Classe BeanInterface :

public interface BeanInterface {

}

Classe BeanInvoker :

@Component
public class BeanInvoker {

    @Autowired
    private List<BeanInterface> list;

    @Autowired
    private Map<String, BeanInterface> map;

    public void say() {
        if (null != list && 0 != list.size()) {
            for (BeanInterface bean : list) {
                System.out.println(bean.getClass().getName());
            }
        } else {
            System.out.println(" list is null !");
        }

        if (null != map && 0 != map.size()) {
            for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "      " + entry.getValue().getClass().getName());
            }
        } else {
            System.out.println("map is null !");
        }
    }
}

Classe de test TestInjection :

@RunWith(BlockJUnit4ClassRunner.class)
public class TestInjection extends UnitTestBase {

    public TestInjection() {
        super("classpath:spring-beanannotation.xml");
    }

    @Test
    public void testMultiBean() {
        BeanInvoker invoker = super.getBean("beanInvoker");
        invoker.say();
    }

}

首先,我们清楚BeanImplOne类和BeanImplTwo类是实现了BeanInterface接口的,在BeanInvoker类里面我们定义了list和map,我们通过@Autowired注解把BeanImplOne类和BeanImplTwo类注解进入其中。那么怎么证实是@Autowired注解把这两个类注入到list或者map中的呢?那么请看if循环语句和foreach循环打印,通过这个逻辑判断,如果能够打印出BeanImplOne类和BeanImplTwo类的路径名,就说明这样是可以的。如果有些小伙伴可能不信,那么可以试着不使用@Autowired注解,看结果怎么样。

测试类没有什么好说的,各位小伙伴有没有注意到@Order注解呢?这里需要解释的就是,如果在@Order注解里面输入执行的数字,比如1或者2,那么打印出来的路径名就会按顺序,也就是说通过指定@Order注解的内容可以实现优先级的功能。

5.@ImportResource注解引入一个资源,对应一个xml文件

6.@Value注解从资源文件中,取出它的key并赋值给当前类的成员变量

案例:@ImportResource和@Value用法分析:

MyDriverManager类:

public class MyDriverManager {

    public MyDriverManager(String url, String userName, String password) {
        System.out.println("url : " + url);
        System.out.println("userName: " + userName);
        System.out.println("password: " + password);
    }

}

config.xml:

<context:property-placeholder location="classpath:/config.properties"/>

StoreConfig类:

@Configuration
@ImportResource("classpath:config.xml")
public class StoreConfig {

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public MyDriverManager myDriverManager() {
        return new MyDriverManager(url, username, password);
    }

这个案例我们使用注解配置jdbc数据库的连接,首先创建一个内含构造器的MyDriverManager类,然后配置config.xml里面的资源文件路径,以便@ImportResource注解获取,最后配置StoreConfig类。(注意url、username、password也必须要和数据库的保持一致哦)

详解StoreConfig类:首先我们定义三个成员变量,然后给每一个成员变量打上一个@value注解,注意@value里面的内容一定是资源文件里面的key值。这里的@ImportResource注解就是指明一个资源文件,在这个资源文件里面获取到对应的数据。那么@Configuration注解是用来干嘛的呢?为什么不用@Component注解呢?其实是这样的,@Component注解用于将所标注的类加载到 Spring 环境中,这时候是需要配置component-scan才能使用的,而@Configuration注解是Spring 3.X后提供的注解,它用于取代XML来配置 Spring。

7.@Bean注解用来标识配置和初始化一个由SpringIOC容器管理的新对象的方法,类似XML中配置文件的d7de7346c94b9644ec904d605d4c96bf

ps:默认的@Bean注解是单例的,那么有什么方式可以指定它的范围呢?所以这里才出现了@Scope注解

8.@Scope注解,在@Scope注解里面value的范围和Bean的作用域是通用的,proxyMode的属性是采用哪一种的单例方式(一种是基于接口的注解,一种是基于类的代理)

案例:@Bean和@Scope用法分析:

    @Bean
    @Scope(value ="session",proxyMode = "scopedProxyMode.TARGET_CLASS")
    public UserPreferences userPreferences(){
        return new userPreferences();
    }

    @Bean
    public service userService(){
        UserService service =new SimpleUserService();
        service.setUserPreferences(userPreferences);
        return service;
    }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn