3. 基於註解方式管理Bean

西瓜為什麼那麼甜發表於2020-12-22

1. 什麼是註解

(1)註解是程式碼中的特殊標記,格式為:@註解名稱(屬性名稱=屬性值, 屬性名稱=屬性值, …)

(2)註解可以作用在類、方法、屬性上面

(3)使用註解的目的:簡化xml配置

2. 使用註解管理Bean

2.1 基於註解方式建立物件

2.1.1 註解說明

  • @Component
  • @Service
  • @Controller
  • @Repository

上面四個註解功能是一樣的,都可以用來建立bean例項,為了區分不同層級的功能,因此建議不同的層級用不同註解進行表示

2.1.2 程式碼實現

  1. 引入依賴

    需要引入apo依賴

    image-20201217105640204

  2. 開啟元件掃描

    <?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">
    
    
        <!-- 開啟元件掃描
                1. 如果掃描多個包,多個包之間使用逗號分隔
                2. 直接掃描上次目錄
         -->
        <context:component-scan base-package="com.study.spring5.demo10"></context:component-scan>
    </beans>
    
  3. 建立UserService類,在類上面新增建立物件的註解

    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    //@Component(value = "userService")
    //@Component
    @Service
    // 等同於在配置檔案中寫 <bean id="userService" class="...">
    // 在註解裡面value屬性值可以省略不寫,預設值就是類名稱的首字母小寫 UserService => userService
    public class UserService {
    
        public void add() {
            System.out.println("service add");
        }
    }
    
  4. 建立主方法

    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("bean10.xml");
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    

2.2 元件掃描配置

UserService類

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;


//@Component(value = "userService")
//@Component
//@Service
@Controller // 由於配置檔案的配置,只能使用@Controller註解才會被掃描到
// 等同於在配置檔案中寫 <bean id="userService" class="...">
// 在註解裡面value屬性值可以省略不寫,預設值就是類名稱的首字母小寫 UserService => userService
public class UserService {

    public void add() {
        System.out.println("service add");
    }
}

xml配置檔案

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


    <!-- 元件掃描配置 只掃描用Controller註解宣告的類
            use-default-filters屬性用來控制是否使用預設filter進行掃描
     -->
    <context:component-scan base-package="com.study.spring5.demo11" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


    <!-- 元件掃描配置 不掃描用Component註解宣告的類 不需要配置 use-default-filters屬性 -->
    <context:component-scan base-package="com.study.spring5.demo11">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    </context:component-scan>
</beans>

主方法

public class Main {

    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("bean11.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.add();
    }
}

2.3 基於註解方式實現屬性注入

2.3.1 註解說明

  • @Autowired

    根據屬性型別進行自動注入

  • @Qualifier

    根據屬性名稱進行注入

  • @Resource

    可以根據型別注入,也可以根據名稱注入

  • @Value

    注入普通型別屬性

2.3.2 程式碼實現

  • @Autowired

    第一步:建立service和dao物件,在service和dao類新增建立物件的註解

    UserService類

    @Service
    public class UserService {
    
        public void add() {
            System.out.println("UserService::add");
        }
    }
    

    UserDao介面

    public interface UserDao {
    
        void add();
    }
    

    UserDao介面實現類UserDaoImpl

    @Repository
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    

    第二步:在service注入dao物件,在UserServiceImpl類新增UserDao型別屬性

    將UserService改為以下內容

    @Service
    public class UserService {
    
        // 定義dao型別屬性,不需要新增set方法
        // 新增註入屬性註解
        @Autowired
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    

    主方法

    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("bean12.xml");
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    
  • @Qualifier

    需要和@Autowired一起使用

    用於當一個介面有多個實現類時候,按照名稱注入指定的實現類

    UserDaoImpl改為

    @Repository(value = "userDaoImpl")
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    

    UserService改為

    @Service
    public class UserService {
    
        // 定義dao型別屬性,不需要新增set方法
        // 新增註入屬性註解
        @Autowired
        // 當有多個實現類時,按照指定的名稱注入實現類,預設不寫的話,則注入類名稱首字母小寫後的類 UserDao => userDao
        @Qualifier(value = "userDaoImpl")
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    
  • @Resource(spring不建議使用)

    JDK11版本及以上需要引用javax.annotation-api才可使用@Resource註解

    image-20201217154919317

    將UserService改為

    @Service
    public class UserService {
    
    //    @Resource
        @Resource(name = "userDaoImpl") // 根據名稱進行注入
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    
  • @Value

    UserService改寫為

    @Service
    public class UserService {
    
    //    @Resource
        @Resource(name = "userDaoImpl") // 根據名稱進行注入
        private UserDao userDao;
    
        @Value(value = "注入的名稱")
        private String name;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
            System.out.println("注入的name值:" + name);
        }
    }
    

2.4 完全註解開發

  1. 建立配置類,替代xml配置檔案

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    // 宣告該類作為配置類
    @Configuration
    // @ComponentScan(basePackages = {"com.study.spring5.demo13"})
    // 等同於<context:component-scan base-package="com.study.spring5.demo13"/>
    @ComponentScan(basePackages = {"com.study.spring5.demo13"})
    public class SpringConfig {
        
    }
    
  2. 編寫UserDao介面

    public interface UserDao {
    
        void add();
    }
    
  3. 編寫UserDaoImpl實現類

    @Repository
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    
  4. 編寫主方法

    public class Main {
    
        public static void main(String[] args) {
            // 載入配置類,通過配置類載入配置,替代掉xml
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    

相關文章