Spring --07.Spring框架中bean管理的常用注解

版权声明:转载请注明原始链接 https://blog.csdn.net/sswqzx/article/details/83860019

Spring中用于管理bean的注解分为四大类:

1)、用于创建对象 @Component/@Coontroller@Service@Repository

2)、用于给对象中的属性注入值@Value、@Autowired、@Qualifier、@Resource

3)、用于改变作用范围@Scope

4)、用于定义生命周期@PostConstruct  @PreDestroy

1、用于创建对象

用于创建对象的有四个:@Component,@Controller,@Service,@Repository

(1)、@Component注解

作用:把资源让Spring来管理、相当于在Xml中配置一个bean

属性:value:指定bean的id值、如果不指定value属性、默认bean的id是当前 类的类名、首字母小写

(2)、@Controller,@Service,@Repository

他们三个注解都是针对一个的衍生注解,他们的作用及属性都是一模一样的。

他们只不过是提供了更加明确的语义化。

@Controller:一般用于表现层的注解。

@Service:一般用于业务层的注解。

@Repository:一般用于持久层的注解。

@Service的用法:修改UserServiceImpl类,把@Component改成@Service

//@Component("userService")
@Service("userService")//@Service加在业务层的bean,value属性指定bean的id
public class UserServiceImpl implements UserService{
    @Override
    public void saveUser() {
        System.out.println("业务层:用户保存...");
    }
}

@Repository的用法:创建UserDao接口:

创建UserDao.java接口和UserDaoImpl.java实现类

package com.day01.dao;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:00 2018/11/8
 */
public interface UserDao {
    public abstract void save();
}
package com.day01.dao.Impl;

import com.day01.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:01 2018/11/8
 */
@Repository("userDao")//@Repository加在dao层的bean,value属性指定bean的id
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("持久层。。。。");
    }
}

applicationContext.xml、要把扫描的包定义为com.day01,不然的其它包的注解就不能识别了

<?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.xsd">

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

测试

package com.day01.test;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 13:35 2018/11/8
 */
public class TestIOC {

    @Test
    public void test2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.save();
    }
}

@Controller:

@Controller("userAction")//@Controller加在web层的bean,value属性指定bean的id
        public class UserAction {
 }

2、用于给对象属性注入值

用于给对象属性注入数据的注解有:

@Value、@Autowired、@Qualifier、@Resource

相当于:<property name=""  ref=""> /<property name="" value="">

<bean id="people" class="com.day01.domain.People">
    <property name="name" value="小刚"></property>
    <property name="address" value="上海"></property>
    <property name="car" ref="car"></property>
</bean>

(1)、@Value

作用:注入基本数据类型和String类型数据

属性:value:用于指定值

修改UserDaoImpl.java、增加一个字符串属性name、通过@Value注解实现

package com.day01.dao.Impl;

import com.day01.dao.UserDao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:01 2018/11/8
 */
@Repository("userDao")//@Repository加在dao层的bean,value属性指定bean的id
public class UserDaoImpl implements UserDao {
    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

    @Override
    public void save() {
        System.out.println("持久层。。。。"+name);
    }
}

测试

    @Test
    public void test2(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.save();
    }

(2)、@Autowired

作用:

自动按照类型注入。
当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时,
使用要注入的对象变量名称作为bean的id,在spring容器查找,找到了也可以注入成功。找不到就报错。

 修改UserServiceImpl类、增加一个对象属性userDao、现通过@Autowired给userDao注入值

package com.day01.service.Impl;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 12:22 2018/11/8
 */
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {

    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

    @Autowired //注入对象类型、招照类型注入
    private UserDao userDao;

    @Override
    public void saveUser() {
        System.out.println("业务层:保存用户。。。。。。"+name);
        userDao.save();
    }
}

UserDaoImpl.java

package com.day01.dao.Impl;

import com.day01.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:01 2018/11/8
 */
@Repository("userDao")//@Repository加在dao层的bean,value属性指定bean的id
public class UserDaoImpl implements UserDao {

    @Override
    public void save() {
        System.out.println("持久层。。。。");
    }
}

 测试类TestIOC.java

package com.day01.test;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 13:35 2018/11/8
 */
public class TestIOC {
    /**
     * 测试注解
     */
    @Test
    public void test1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ac.getBean("userService");
        userService.saveUser();
    }

}

(3)、@Qualifier

作用:

在自动按照类型注入的基础之上,再按照Bean的id注入。
它在给字段注入时不能独立使用,必须和@Autowire一起使用;但是给方法参数注入时,可以独立使用。

 属性:value:指定bean的id。

创建UserDao接口的第二个实现类UserDaoImpl2.java

package com.day01.dao.Impl;

import com.day01.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:36 2018/11/8
 */
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
    @Override
    public void save() {
        System.out.println("持久层:2222.。。。。。。。");
    }
}

测试

    @Test
    public void test1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ac.getBean("userService");
        userService.saveUser();
    }

 

测试发现、UserServiceImpl中注入的还是第一个UserDaoImpl,因为当有多个bean都满足的情况下,

优先注入bean的id与属性的名字一样的bean;想指定注入UserDaoImpl2,需要使用@Qualifier注解根据名字来注入

UserServiceImpl.java

package com.day01.service.Impl;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 12:22 2018/11/8
 */
//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {

    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

    @Autowired //注入对象类型、招照类型注入
    @Qualifier("userDao2")
    private UserDao userDao;

    @Override
    public void saveUser() {
        System.out.println("业务层:保存用户。。。。。。"+name);
        userDao.save();
    }
}

测试TestIOC.java

package com.day01.test;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 13:35 2018/11/8
 */
public class TestIOC {
    /**
     * 测试注解
     */
    @Test
    public void test1(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ac.getBean("userService");
        userService.saveUser();
    }
    
}

修改UserServiceImpl.java再次测试、就会发现UserServiceImpl中注入的是UserDaoImpl2

(4)、@Resource

作用:直接按照Bean的id注入。它也只能注入其他bean类型。

属性:name:指定bean的id。

修改UserServiceImpl类,使用@Resource给userDao注入值。@Resource是按照bean的id来注入,只能注入对象类型

UserDaoImpl2.java实现类

package com.day02.dao.Impl;

import com.day02.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:36 2018/11/8
 */
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
    @Override
    public void save() {
        System.out.println("持久层:2222.。。。。。。。");
    }
}

UserServiceImpl.java实现类

package com.day02.service.Impl;

import com.day02.dao.UserDao;
import com.day02.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;


import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 12:22 2018/11/8
 */
//@Component("userService")
//@Scope("singleton")
@Service("userService")
public class UserServiceImpl implements UserService {


    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

//    @Autowired //注入对象类型、招照类型注入
//    @Qualifier("userDao")
    @Resource(name="userDao2")
    private UserDao userDao;

    public UserServiceImpl() {
        System.out.println("调用了无参构造。。。。。");
    }

    @PostConstruct
    public void init(){
        System.out.println("---------------调用init方法。。。。");
    }

    @Override
    public void saveUser() {
        System.out.println("业务层:保存用户。。。。。。"+name);
        userDao.save();
    }

    @PreDestroy
    public void destory(){
        System.out.println("-------------------调用了destroy方法。。。。。");
    }
}

测试类:TestIOC.java

package com.day02.test;

import com.day02.dao.UserDao;
import com.day02.service.UserService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 13:35 2018/11/8
 */
public class TestIOC {
    private ClassPathXmlApplicationContext ac = null;
    @Before
    public void setUp(){
         ac= new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    /**
     * 测试注解
     */
    @Test
    public void test1(){
        UserService userService = (UserService) ac.getBean("userService");
        userService.saveUser();
        ac.close();
    }
}

注意:@Resource注解不起作用情况、本人亲测JDK9不起作用、换成JDK8就好了。

3、用于改变作用域范围

@Scope

作用:指定bean的作用范围

属性:value:指定范围的值。取值:singleton   prototype  request  session  globalsession

修改UserServiceImpl,在该类上加@Scope注解,指定该类是多例的的,默认是单例的。给该类显示指定一个无参构造方法,方便测试

package com.day01.service.Impl;

import com.day01.dao.UserDao;
import com.day01.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 12:22 2018/11/8
 */
//@Component("userService")
@Service("userService")
@Scope("prototype")
public class UserServiceImpl implements UserService {

    public UserServiceImpl() {
        System.out.println("调用了无参构造。。。。。");
    }

    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

    @Autowired //注入对象类型、招照类型注入
    @Qualifier("userDao2")

    //@Autowired()

    private UserDao userDao;


    @Override
    public void saveUser() {
        System.out.println("业务层:保存用户。。。。。。"+name);
        userDao.save();
    }
}

测试TestIOC.java

    @Test
    public void test3(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) ac.getBean("userService");
        UserService userService1 = (UserService) ac.getBean("userService");
        System.out.println(userService1+ " = " +userService);
    }

4、用于定义生命周期

相当于applicationContent.xml中的

<bean id="" class="" init-method="" destroy-method="" />

@PostConstruct注解  @PreDestory注解

(1)、@PostConstruct

说明:@PostConstruct加在方法上,指定bean对象创建好之后,调用该方法初始化对象,类似于xml的init-method方法。修改UserServiceImpl类,在其中增加一个init方法,在该方法上指定@PostConstruct注解

(2)、@PreDestory

@PreDestory加在方法上,指定bean销毁之前,调用该方法,类似于xml的destory-method方法。修改UserServiceImpl类,在该类中增加一个destroy方法,在该方法上加@PreDestroy注解

UserDaoImpl.java

package com.day02.dao.Impl;

import com.day02.dao.UserDao;
import org.springframework.stereotype.Repository;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:36 2018/11/8
 */
@Repository("userDao2")
public class UserDaoImpl2 implements UserDao {
    @Override
    public void save() {
        System.out.println("持久层:2222.。。。。。。。");
    }
}

UserServiceImpl.java

package com.day02.service.Impl;

import com.day02.dao.UserDao;
import com.day02.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;


import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 12:22 2018/11/8
 */
//@Component("userService")
//@Scope("singleton")
@Service("userService")
public class UserServiceImpl implements UserService {


    @Value("小罗")//@Value给基本类型和字符串类型注入值,value属性指定要注入的值
    private String name;

//    @Autowired //注入对象类型、招照类型注入
//    @Qualifier("userDao")
    @Resource(name="userDao2")
    private UserDao userDao;

    public UserServiceImpl() {
        System.out.println("调用了无参构造。。。。。");
    }

    @PostConstruct
    public void init(){
        System.out.println("---------------调用init方法。。。。");
    }

    @Override
    public void saveUser() {
        System.out.println("业务层:保存用户。。。。。。"+name);
        userDao.save();
    }

    @PreDestroy
    public void destory(){
        System.out.println("-------------------调用了destroy方法。。。。。");
    }
}

TestIOC.java测试类

package com.day02.test;

import com.day02.dao.UserDao;
import com.day02.service.UserService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 13:35 2018/11/8
 */
public class TestIOC {
    private ClassPathXmlApplicationContext ac = null;
    @Before
    public void setUp(){
         ac= new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    /**
     * 测试注解
     */
    @Test
    public void test1(){
        UserService userService = (UserService) ac.getBean("userService");
        userService.saveUser();
        ac.close();
    }
}

注意:@PreDestory和@PostConstruct在JDK9上不起作用、换成JDK8就好了。

注解总结:

与创建Bean对象相关:

@component     @Controller   @Service   @Repository

与属性注入值相关:

@Value   @Autowired   @Qulifier  @Resource

与范围相关

@Scope   

与生命周期相关

@PostConstruct  @PreDestroy

5、XML和注解的比较

注解的优势:配置简单,维护方便。(我们找到了类,就相当于找到了配置)

XML的优势:修改时,不用改源码。不涉及重新编译和部署。

Xml和注解的比较
  基于xml配置 基于注解配置
Bean定义 <bean id="" class="" /> @Component衍生类@Repository@Service@Controller
Bean名称 通过id或name指定 @Component("person")
Bean注入 <property>或者通过p命名空间 @Autowired按类型注入@Qualifier按名称注入
生命令过程、Bean作用范围 init-method   destroy-method 范围Scope属性 @PostConstruct 初始化 @PreDestroy销毁 @Scope设置作用范围
适合场景 Bean来自第三方、使用其它 Bean的实现类由用户自已开发

猜你喜欢

转载自blog.csdn.net/sswqzx/article/details/83860019