Spring中的Bean

Spring中的Bean,第1张

Spring中的Bean

文章目录
  • 一、bean的配置
    • 如何使用:
      • 1、创建实体类
      • 2、创建bean
      • 3、测试
  • 二、Bean的作用域
    • 测试常用的作用域
  • 三、基于Annotation的装配
    • 使用
    • value的使用:
    • @Autowired的使用:
  • 四、自动装配
    • byName和ByType:

一、bean的配置

Spring中,xml配置文件的根元素是< beans>,< beans>中可以包含多个< bean>子元素,每一个
< bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。

< bean>子元素中包含多个属性和子元素如下:

  • id:Bean的唯一标识符,只有通过它,程序才可以使用
  • name:Spring容器通过此属性进行配置和管理,可以通过name为Bean指定多个别名,每个别名之间通过逗号隔开
  • class:指定Bean的实现类,它必须使用类的全限定名
  • scope:用于设定Bean实例的作用域,其属性值有singleton(单例),prototype(原型),request,session,application,websocket,默认值为singleton
  • constructor-arg:< bean>元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的index属性指定构造参数的序号(从0开始),type属性指定构造参数的类型,参数值可以通过ref属性或者value属性直接指定,也可以通过ref或value子元素指定
  • property:< bean>元素的子元素,用于调用Bean实例中的setter()方法完成属性赋值,从而完成依赖注入。该元素的name属性指定Bean实例中的响应属性名,ref属性或value属性用于指定参数值
  • ref:< constructor-arg>、< property>等元素的属性或子元素,可以用于指定对Bean工厂中某个Bean实例的引用
  • value:< constructor-arg>、< property>等元素的属性或子元素,可以用于直接给定一个常量值
  • list:用于封装List或数组属性的依赖注入
  • set:用于封装Set类型属性的依赖注入
  • map:用于封装Map类型属性的依赖注入
  • entry:< map>元素的子元素,用于设置一个键值对。其key属性指定字符串类型的键值,ref属性或value属性直接指定其值,也可以通过ref或value子元素指定其值

注:如果在Bean中未指定id和name,那么Spring会将class值当做id使用

如何使用: 1、创建实体类
package pojo;
//User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
}
package pojo;

import java.util.*;
//Student类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List hobbys;
    private Map card;
    private Set games;
    private Properties info;
    private String wife;
}
package pojo;
//Address类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Address {
    private String address;   
}
2、创建bean





    
        
    

    
       
        

        
        

        
        
            
                红楼梦
                西游记
                水浒传
                三国
            
        

        
        
            
                看电影
                敲代码
                听歌
            
        

        
        
            
                
                
            
        

        
        
            
                lol
                王者荣耀
            
        

        
        
            
        

        
        
            
                19010101
                男性
                小明
                123456
            
        

    


3、测试
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.toString());

        

    }
二、Bean的作用域

在Spring容器中创建一个Bean实例时,我们需要考虑Bean的作用域,是否每次使用这个对象的时候,都被容器重新创建,还是一直指向第一次创建的实例对象。

重点需要掌握的就是singleton和prototype

  • singleton:单例,使用singleton定义的Bean在Spring容器中将只有一个实例,也就是说,无论有多少个Bean引用它,始终指向同一个对象,这也是Spring容器默认的作用域
  • prototype:原型,每次通过Spring容器获取prototype定义的Bean时,容器都会创建一个新的Bean实例

还有request、session、globalSession、application、websocket 5种作用域

测试常用的作用域
public class Scope {
}



    

    


public class test {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println(context.getBean("scope"));
        System.out.println(context.getBean("scope"));
        System.out.println("==========================");
        System.out.println(context.getBean("scope1"));
        System.out.println(context.getBean("scope1"));
    }
}

结果

比对地址,就可以得出,单例和原型的区别!

三、基于Annotation的装配

在Spring中,尽管使用xml配置文件可以实现Bean的装配工作,但如果应用中有很多Bean,就会导致xml配置文件过于臃肿,给以后的维护和升级代码一定的困难。为此,Spring提供了很方便的Annotation(注解)支持。

  • @Component:可以使用此注解描述Spring中的Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次,使用时只需要将该注解标注在相应类上即可。
  • @Repository:用于数据访问层(DAO层)的类标识为Spring中的Bean,其功能与@Component相同
  • @Service:通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同
  • @Controller:通常作用在控制层(如Spring MVC的Controller层),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同
  • @Autowired:用于对Bean的属性变量、属性的setter()方法及构造方法进行标注,配合对应的注解完成Bean的自动配置工作。默认按照Bean的类型进行装配
  • @Resource:作用与@Autowired一样,区别在于@Autowired默认按Bean类型装配,而@Resource默认按照Bean实例名称进行装配。

@Resource中有两个重要属性:name和type。Spring将name属性解析为Bean实例名称,type属性解析为Bean实例类型。
若指定name属性,则按照实例名称进行装配;
若指定type属性,则按Bean类型进行装配;
若都不指定,则先按Bean实例名称装配,不能匹配时再按照Bean类型进行装配;若都无法匹配,则抛出异常

  • @Qualifier:与 @Autowired注解搭配使用,会将默认的按Bean类型装配修改为按Bean的实例名称装配,Bean的实例名称由@Qualifier注解的参数指定
使用

创建接口和接口实现类

//UserController类,特意删除了接口,用来比较
@Controller("UserControllerImpl")
public class UserControllerImpl {

    public void save() {
        System.out.println("UserControllerImpl.sava()");
    }
}
//UserMapper接口
public interface UserMapper {
    public void save();
}
//UserMapperImpl类
@Repository("UserMapperImpl")
public class UserMapperImpl implements UserMapper {
    @Override
    public void save() {
        System.out.println("UserMapper.sava()");
    }
}
//UserService接口
public interface UserService {
    public void save();
}
//UserServiceImpl类
@Service("UserServiceImpl")
public class UserServiceImpl implements UserService{
    @Override
    public void save() {
        System.out.println("UserServiceImpl.sava()");
    }
}

在applicationContext.xml中注册

	
	
	
    
    
    

测试:

public class test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        context.getBean("UserMapperImpl", UserMapper.class).save();
        context.getBean("UserServiceImpl", UserService.class).save();
        context.getBean("UserControllerImpl", UserControllerImpl.class).save();

    }
}

结果:

上面的三种注解方式,都可以使用Autowired替换,达到同样的效果,但是为了开发规范,建议使用各个类的注解方式,规范代码编写。

value的使用:
@Component
public class User {
    //value相当于
    //
    //也可以在set方法中注解
    @Value("二十四桥明月夜")
    public String name;

    //相同
    //public String name = "二十四桥明月夜";
}



    
    
    


测试:

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        System.out.println(user.name);
    }
}

@Autowired的使用:
public class Cat {

    public void shout(){
        System.out.println("miao");
    }
}
public class Dog {
    public void shout(){
        System.out.println("wang");
    }
}
public class People {

    //如果显式的定义了Autowired的required属性为false,说明这个对象可以为空,否则不可以
    @Autowired
    private Cat cat;
    @Autowired
    @Qualifier(value = "dog")//指定bean中的id名字,在Bean中必须有它的映射,且id=dog
    private Dog dog;
    private String name;


}



    

    
    
    
    


测试:

public class MyTest {

    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        People people = context.getBean("people", People.class);
        people.getDog().shout();
        people.getCat().shout();
        
    }
}

结果:

四、自动装配

Spring的< bean>元素中包含一个autowire属性,可以通过设置autowire属性值来自动装配Bean。

  • default:默认值,由< bean>的上级标签< beans>的default-autowire属性值确定。例如< beans default-autowire=“byName”>,该< bean>元素中的autowire属性对应的属性值为byName
  • byName:根据属性的名称自动装配。容器将根据名称查找与属性完全一致的Bean,并将其属性自动装配
  • byType:根据属性的数据类型自动装配,如果一个Bean的数据类型兼容另一个Bean中属性的数据类型,则自动装配
  • constructor:根据构造函数参数的数据类型进行byType模式的自动装配
  • no:在默认情况下,不适用自动装配,Bean依赖必须通过ref元素定义
byName和ByType:

创建的实体类在Autowried中

  • byName自动装配
	
    
    


    



    
        
        
    
  • byType自动装配
	
    
    
    

    

报错的图片:

在注册bean的时候,可以省略id,自动装配

小结:

  • byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性和set方法的值一致(不区分大小写)
  • byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5684287.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存