一、概念
spring bean的注入大致分为两类:XML配置 与 注解方式
XML配置:set注入、构造函数注入,P标签,静态工厂方法与实例工厂方法;
注解方式: @Autowired,@Resource,@Qualifier。
注解需要注意:
@Autowired:是自动装配,默认采用类型ByType,依赖对象必须存在,否则抛出异常,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) 。
@Qualifier("cusInfoService"):根据名称装配,一般与Autowired结合使用。
@Resource(name="cusInfoService"):默认根据名称,可以指定名称或类型,也可以同时指定。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
注解方式注意:
@Configuration:标识配置类,相当于spring配置文件
@ComponentScan("com.hello.bean"):扫描包路径。
@Component:用来标识一个bean,用于spring的IOC容器就是通过扫描加注解的方式将对象放入容器管理。
@Component细分@Controller,@Service,@Repository,只是为了分类,作用相同!
@Controller("Bean的名称"):定义控制层Bean,如Action
@Service("Bean的名称"):定义业务层Bean
@Repository("Bean的名称"):定义DAO层Bean
123456789101112131415161718192021222324252627
二、案例
-
xml配置
/**
-
书
-
@author zrj
-
@date 2020/12/16
-
@since V1.0 **/ public class Book { private String bookName; private String bookAuthor;
public Book() { }
public Book(String bookName, String bookAuthor) { this.bookName = bookName; this.bookAuthor = bookAuthor; }
public String getBookName() { return bookName; }
public void setBookName(String bookName) { this.bookName = bookName; }
public String getBookAuthor() { return bookAuthor; }
public void setBookAuthor(String bookAuthor) { this.bookAuthor = bookAuthor; }
@Override public String toString() { return "Book{" + "bookName='" + bookName + ''' + ", bookAuthor='" + bookAuthor + ''' + '}'; } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344
/**
-
订单类
-
@author zrj
-
@date 2020/12/17
-
@since V1.0 **/ public class Orders { private String orderName; private double orderPrice;
public Orders() { }
public Orders(String orderName, double orderPrice) { this.orderName = orderName; this.orderPrice = orderPrice; }
public String getOrderName() { return orderName; }
public void setOrderName(String orderName) { this.orderName = orderName; }
public double getOrderPrice() { return orderPrice; }
public void setOrderPrice(double orderPrice) { this.orderPrice = orderPrice; }
@Override public String toString() { return "Orders{" + "orderName='" + orderName + ''' + ", orderPrice=" + orderPrice + '}'; } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344
/**
-
汽车
-
@author zrj
-
@date 2020/12/16
-
@since V1.0 **/ public class Car { private String carName; private String carAuthor;
public Car() { }
public Car(String carName, String carAuthor) { this.carName = carName; this.carAuthor = carAuthor; }
public String getCarName() { return carName; }
public void setCarName(String carName) { this.carName = carName; }
public String getCarAuthor() { return carAuthor; }
public void setCarAuthor(String carAuthor) { this.carAuthor = carAuthor; }
@Override public String toString() { return "Car{" + "carName='" + carName + ''' + ", carAuthor='" + carAuthor + ''' + '}'; } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445
/**
-
工厂注入
-
@author zrj
-
@date 2020/12/17
-
@since V1.0 **/ public class CarFactory {
/**
- 静态工厂,返回一个Car的实例对象 */ public static Car getCar() { return new Car( "奔驰", "梅赛德斯你" ); }
/**
- 实例工厂,返回一个Car的实例对象 */ public Car getNewCar() { return new Car( "帕梅拉", "保时捷" ); } } 123456789101112131415161718192021222324
123456789101112131415161718192021222324252627282930<!--1 set方法注入属性--> <bean id="book" class="com.spring5.bean.Book"> <!--使用property完成属性注入,name:类里面属性名称,value:向属性注入的值 --> <property name="bookName" value="平凡世界"></property> <property name="bookAuthor" value="路遥"></property> </bean> <!--2 有参数构造注入属性--> <bean id="orders" class="com.spring5.bean.Orders"> <constructor-arg name="orderName" value="电脑"></constructor-arg> <constructor-arg name="orderPrice" value="12"></constructor-arg> </bean> <!--3 p标签注入--> <bean id="car" class="com.spring5.bean.Car" p:carName="幻影" p:carAuthor="劳斯莱斯"/> <!--4 静态工厂注入--> <bean id="car2" class="com.spring5.bean.CarFactory" factory-method="getCar"/> <!--5 实例工厂注入--> <bean id="carFactory" class="com.spring5.bean.CarFactory"/> <bean id="cars" factory-bean="carFactory" factory-method="getNewCar"/>
package com.spring5.test;
import com.spring5.bean.Book; import com.spring5.bean.Car; import com.spring5.bean.Orders; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
-
spring测试类
-
@author zrj
-
@date 2020/12/13
-
@since V1.0 **/ public class SpringTest {
/**
- 加载spring配置文件 */ ApplicationContext context = new ClassPathXmlApplicationContext( "bean1.xml" );
/**
- set注入 */ @Test public void bookTest() { Book book = context.getBean( "book", Book.class ); System.out.println( book.toString() ); }
/**
- 构造函数 */ @Test public void orderTest() { Orders order = context.getBean( "orders", Orders.class ); System.out.println( order.toString() ); }
/**
- p空间注入 */ @Test public void curTest() { Car car = context.getBean( "car", Car.class ); System.out.println( car.toString() ); }
/**
- 静态工厂注入 */ @Test public void curTest2() { Car car = context.getBean( "car2", Car.class ); System.out.println( car.toString() ); }
/**
- 实例工厂注入 */ @Test public void curTest3() { Car car = context.getBean( "cars", Car.class ); System.out.println( car.toString() ); } }
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
-
-
注解方式
package com.hello.config;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;
/**
- springBean配置类
- @author 20023262
- @date 2020/12/18
- @since 1.0 */ @Configuration @ComponentScan("com.hello.bean") public class SpringBeanConfiguration { }
1234567891011121314151617
package com.hello.bean;
import lombok.*; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
/**
- 汽车
- @author 20023262
- @date 2020/12/18
- @since 1.0 */ @Data @Builder @ToString @Scope(value = "prototype") @Component(value = "car") public class Car { private String name; private String auth; }
1234567891011121314151617181920212223
package com.hello.bean;
import lombok.Builder; import lombok.Data; import lombok.ToString; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
/**
- 电脑
- @author 20023262
- @date 2020/12/18
- @since 1.0 */ @Data @Builder @ToString @Scope(value = "prototype") @Component(value = "computer") public class Computer { private String brand; private String name; }
12345678910111213141516171819202122232425
package com.hello.bean;
import lombok.Builder; import lombok.Data; import lombok.ToString; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
/**
- 手机
- @author 20023262
- @date 2020/12/18
- @since 1.0 */ @Data @Builder @ToString @Scope(value = "prototype") @Component(value = "mobile") public class Mobile { private String brand; private String name; }
12345678910111213141516171819202122232425
package com.hello.bean;
import lombok.Builder; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
-
用户类
-
Component(value = "user") //相当于在配置文件中
-
Scope(value = "prototype") //配置创建对象是否是以单列模式进行创建
-
-
Autowired:自动装配,默认按type注入
-
Resource(name = "book"):默认按name注入,可以通过name和type属性进行选择性注入
-
Qualifier:按照名称装配
-
@author 20023262
-
@date 2020/12/18
-
@since 1.0 */ @Scope(value = "prototype") @Component(value = "user") public class User { private String name; private int age;
@Autowired(required = false) private Car car;
@Resource(name = "mobile") private Mobile mobile;
@Qualifier("computer") @Autowired(required = false) private Computer computer;
public User() { }
public User(String name, int age, Car car, Mobile mobile, Computer computer) { this.name = name; this.age = age; this.car = car; this.mobile = mobile; this.computer = computer; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public Car getCar() { return car; }
public void setCar(Car car) { this.car = car; }
public Mobile getMobile() { return mobile; }
public void setMobile(Mobile mobile) { this.mobile = mobile; }
public Computer getComputer() { return computer; }
public void setComputer(Computer computer) { this.computer = computer; }
@Override public String toString() { return "User{" + "name='" + name + ''' + ", age=" + age + ", car=" + car + ", mobile=" + mobile + ", computer=" + computer + '}'; } }
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
package com.hello.bean;
import com.hello.config.SpringBeanConfiguration; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
-
springBean注解注入测试类
-
@author 20023262
-
@date 2020/12/18
-
@since 1.0 */ public class SpringBeanTest {
@Test public void springBeanTest() { // 加载配置类 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringBeanConfiguration.class); User user = applicationContext.getBean("user", User.class); System.out.println("user:" + user);
}
}
总结:
感谢大家阅读完本文章,也为大家准备了Java进阶的架构资料,需要的朋友可以关注微信公众号【Java程序员聚集地】获取架构资料。