获取Bean的两种方法

简单获取Bean的两种方法

在之前使用spring时我们都是使用xml语句进行对象注入,而如果对于一个大型项目采用这种方法,需要编写大量的xml对象注入语句,使用起来可以说是非常不方便了。那么使用什么方法才可以使得我们并不需要编写大量的代码就可以写出优秀的程序呢?

五大类注解由此而生,对于一个类对象只需要添加一个注解,然后就可以获取到添加该注解的bean对象。

在添加注解之前我们需要在配置文件中修改文件中的字段:

<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="com.controller">
    </content:component-scan>
    <!-- 注意:base-package="这里填写的是类创建的路径" -->
</beans>

将配置文件修改之后,我们需要读懂配置文件中添加的字段。

<content:component-scan>这个标签如果在xml文件中进行配置,就会在base-package这个目录下自动扫描以下五大类注解,然后将这些类加注册为bean

  • @Controller:控制层

归属于业务逻辑层,用来控制用户行为和检查仓库数据的有效性

  • @Repository:数据仓库层

    归属于持久层,直接调用数据库的数据,通常每个数据表只存在一个需要@repository注解类

  • @Service:服务层

    使用数据仓库持久化的特性将数据传递给控制层(不直接与数据库中数据交互,相对于数据控制中心)

  • @Component:组件层

    归属于公共方法类,提供一些五大类注解都会使用的方法

  • @Configuration:配置层

    一般用于当前项目的配置,一般每个项目的配置文件都会存在不同

使用示例:

//一个添加@controller的对象被注入时
@Controller
public class Employ {
    public void addOne(){
        System.out.println("录用一个新人");
    }
}

App.class获取bean对象:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        Employ employ = context.getBean("employ", Employ.class);
        employ.addOne();
    }
}

在这里插入图片描述

可以看到使用了@Controller的类的确被注册。

那么对于调用Bean对象时需要注意什么?

在使用bean标签注入对象时,语法如下:

<bean class="User" id="user">

表示类名为:User,引用时使用id也就是user,意味着user就是bean注册时使用的名称。而当我们使用五大类注解时如果直接使用默认名称,与类名有什么关联!在上面我们举例时默认使用了小写的类名,然后可以获取到bean对象,而如果本来就是小写的类我们又如何去获取,如果是一个全部字母为大写的类又是如何注册Bean对象的?

打开源码:

在这里插入图片描述

public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
    //判断首字母和第二个字符是不是大写,如果是!返回原来的类名作为bean的名称
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
    	//如果前两个字符串不是大写,就创建一个新字符数组保存原来的字符串,然后将第一个字符改为小写
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }

根据以上源码可以得出Bean对象命名的三种规则:

  • 当首字母为大写时,将首字母改为小写,其他不变
  • 当首字母为小写时,使用原类名进行调用
  • 当前两个字母为大写时,使用原类名进行调用

所有我们在编写一个类对象时,不能随意命名,要看懂spring中对于bean对象有不同要求然后获取bean对象时进行修改。

五大类注解自定义名称

在五大类使用时需要注意名称的大小写来注册一个Bean对象,那么有没有更加方便的定义方法呢?

添加Bean自定义名称

@Controller(value="Bean1")

在之后的使用中就可以使用自定义名称来作为Bean名称来调用对象。要注意一旦使用了自定义的名称作为Bean对象,原来的类名就不能使用了。

三种bean注入

除了使用五大类注解来注册一个对象,我们还可以使用@Bean去针对性的注入一个方法或者对象,需要注意的是@Bean对象需要配合五大类注解一起使用,单独使用是无法起效的。

在注册一个类时,在类中使用了Bean注解的方法或者对象都会被一同注入。

例如在刚刚的员工方法,我们掉用了addOne时在控制台打印信息。而在addOne上添加@Bean注解后,直接获取Employ对象时在控制台就会打印信息。相对于另外新注册了一个Bean对象,可以直接使用context.getBean("bean的名称");

//App------------间接调用Bean
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        Employ employ = context.getBean("employ", Employ.class);
    }
}
//App------------直接调用Bean
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new context.getBean("addOne");
    }
}

//Employ
@Controller
public class Employ {
    @Bean
    public void addOne(){
        System.out.println("录用一个新人");
    }
}

输出相同:

在这里插入图片描述

上面中的五大类注解可以进行自定义名称,同样的@Bean也可以自定义名称来作为Bean对象。

//语法1-----可加{}命名为多个名称
@Bean("add")
public void add() {
    System.out.println("Do UserRepository add method");
}
//语法2-----可加{}命名为多个名称
@Bean(name = "add")
public void add() {
    System.out.println("Do UserRepository add method");
}
//语法3-----可加{}命名为多个名称
@Bean(values = "add")
public void add() {
    System.out.println("Do UserRepository add method");
}

命名多个名称是为了让程序更加易读。

public @interface Bean {
    @AliasFor("name")
    String[] value() default {};
    @AliasFor("value")
    String[] name() default {};
    /** @deprecated */
    @Deprecated
    Autowire autowire() default Autowire.NO;
    boolean autowireCandidate() default true;
    String initMethod() default "";
    String destroyMethod() default "(inferred)";
}

这个是关于bean命名的源码:

  1. namevalue:可以看到name默认调用bean是使用方法名,namevalue可以作为多个命名存在。
  2. Autowire:装配默认不开启自动装配功能
  3. initMethod:初始化代码,不常用
  4. destroyMethod:销毁操作,如果程序使用了close或者shutdown,会自动销毁
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
获取Bean 对象后,可以通过反射机制调用 Bean 中的方法,包括有参方法。以调用有参方法为例,以下是一种通用的实现方法: ```java // 获取 Bean 对象 Object bean = applicationContext.getBean("beanName"); // 获取方法对象 Method method = bean.getClass().getMethod("methodName", arg1.getClass(), arg2.getClass(), ...); // 调用方法 Object result = method.invoke(bean, arg1, arg2, ...); ``` 其中,methodName 是要调用的方法的名称,arg1、arg2、... 是方法的参数。需要注意的是,getMethod 方法需要传入参数的类型,如果有多个参数,则需要依次传入每个参数的类型。如果方法中的参数类型不确定,可以使用 Object 类型代替,但需要注意类型转换的问题。 例如,假设有一个名为 UserService 的 Bean,其中有一个名为 addUser 的方法,该方法有两个参数:String 类型的 name 和 Integer 类型的 age。可以通过以下方式调用该方法: ```java // 获取 Bean 对象 UserService userService = applicationContext.getBean(UserService.class); // 获取方法对象 Method addUserMethod = userService.getClass().getMethod("addUser", String.class, Integer.class); // 调用方法 String name = "张三"; Integer age = 20; Object result = addUserMethod.invoke(userService, name, age); ``` 以上代码中,我们首先通过 applicationContext.getBean 方法获取了 UserService 类型的 Bean 对象,然后通过 getMethod 方法获取了 addUser 方法的 Method 对象,最后通过 invoke 方法调用了 addUser 方法,并传入了 name 和 age 两个参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值