spring之常用的注解

注解本身没有功能的,就和 xml 一样。注解和 xml 都是一种元数据,元数据即解释数据的数据,这就是所谓配置。

spring中包含的注解

1.生命Bean注解

@Controller:控制器层【controller】,一般都在控制层使用

@Service:业务逻辑层【service】,一般都在业务逻辑层使用

@Repository:数据访问层【dao】,一般都在数据访问层使用

@component:给不属于以上基层组件的加此注解,偷懒的话可以在所有层使此注解。

注意:虽然我们把注解分成给不同层次加,但是在spring看来注解可以在任意层使用,spring底层不会给具体的层次验证注解,这么写的目的只是为了提高可读性,最偷懒的就是给spring容器中的Bean对象直接添加@component注解。

代码:

  <properties>
        <lombok.version>1.18.10</lombok.version>
        <spring.version>5.2.3.RELEASE</spring.version>
        <logging.version>1.2</logging.version>
        <alibaba.version>1.1.8</alibaba.version>
        <mysql.version>8.0.17</mysql.version>
        <junit.version>4.12</junit.version>
    </properties>

    <dependencies>
        <!--引入common-logging-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${logging.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${alibaba.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

使用注解的时候需要告诉包,在那个包下面去扫描,一般定义的时候写上相同包的路径,context:component-scan 需要导入命名空间 没有配置指定的扫描包路径,会报异常找不到想要的Bean对象:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'personController' available

配置扫描包需要先导入命名空间,一般都是自动导入,没办法自动导入就得自己手写

xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context 
https://www.springframework.org/schema/context/spring-context.xsd

 applicationContext.xml 扫包配置

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

测试代码

package com.zcm.test;

import com.zcm.spring01.controller.*;
import org.junit.*;
import org.springframework.context.support.*;

/**
 * @program: demo
 * @ClassName:Test01
 * @Description:
 * @Author:zcm
 * @Date:2021/2/25 15:05
 */
public class Test01 {

    @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        PersonController controller = context.getBean("applicationContext.xml", PersonController.class);
        controller.getPerson();
    }
}

 使用注解的时候没有XML中的id和class一样来识别,如何来识别Bean对象的呢?默认是当前的类对象的首字母小写后作为id来识别的,如果需要改变名称在此注解上面加value的参数值即可。

@Controller("personController")
public class PersonController {}
@Service("personService")
public class PersonServiceImpl implements PersonService {}
@Repository("personDao")
public class PersonDao {}
@Component("config")
public class Config {
    public void get() {
        System.out.println("这个是配置文件~~~");
    }
}

2.自动注入的注解

@Autowired:spring提供的

@Resource:JDK提供的

    @Autowired
    private PersonService personService2;
    @Resource
    private PersonService personService2;

注意

@Autowired注解,默认情况下按照ByType来进行装配的,如果找不到就报错,找到直接赋值,需要注意的是,如果有多个类型一样的Bean对象,此时会直接按照id查找,默认的id是类名首字母小写【驼峰的命名格式】,找到了直接注入,不然就报错,如果想要自己规定命名可以通过注解@Qualifier,当@Autowired添加在方法上的时候,此方法在创建对象的时候回默认调用,同时方法中的参数会自动装配。

@Qualifier:注解也可以定义在方法参数列表中,可以指定当前属性的id的属性。将名字指定成personService之后,personService2就会被覆盖了。

    @Autowired
    @Qualifier("personService")
    private PersonService personService2;

@Resource和@Autowired都可以主动注入,但是他们之间还是有区别的?

@Resource可以在其他的框架中使用,@Autowired支持的比较单一,@Resource是按照名称进行装配的,如果名字找不到,那么就使用类型装配 而@Autowired是按照类型进行装配,如果类型找不到会使用使用名字进行查找装配,若果找到两个相同类型的Bean,又根据名字找不到,这时候运行就会包异常:

dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.zcm.spring01.service.PersonService' available: expected single matching bean but found 2: personService,personServiceImpl2

3.注解的Bean作用域

在XML文件中可以配置Bean对象作用域,在注解中也有可以使用@Scope(value = "prototype")【多例】或者@Scope(value = "Singleton")【单例】

@Scope(value = "prototype")
@Controller("personController")
public class PersonController {}

4.扫描包范围

   在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean

注意:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者。另外<context:annotation-config/>还提供了两个子标签

1.        <context:include-filter>

2.       <context:exclude-filter>

include-filter:表示要包含扫描的注解,一般不会定义此规则,但是如果引入的第三方包中包含注解,此时就需要使用此标签来进行标识。

exclude-filter:表示要排除扫描的注解,使用较多 。

type:规则的类型

expression:表达式

assignable:可以指定对应的类的名称。但是表达式必须是完全限定名

annotation:按照注解来进行排序,但是表达式中必须是注解的完全限定名

regex:使用正则表达式的方式,一般不用

aspectj:使用切面的方式,一般不用

custom:使用自定义的方式,可以自己定义自己的筛选规则,一般不用

问题:如果现在要求只扫描controller包下的类,不扫描配置包中的Config类。

    <context:component-scan base-package="com.zcm.spring01">
        <!--        只扫描-->
        <context:include-filter expression="com.zcm.spring01.controller.PersonController" type="assignable"/>
        <!--       不扫描-->
        <context:exclude-filter type="assignable" expression="com.zcm.spring01.config.Config"/>

    </context:component-scan>

注意:加上这个配置之后,这时候获取config,Controller类及它的子包service下注解@Service,@Resorce之外的类就会报异常:

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值