Ioc和Ao使用扩展
一、Bean作用域
spring容器创建的时候,会将所有配置的bean对象创建出来,默认bean都是单例的。代码通过getBean()方法从容器获取指定的bean实例,容器首先会调用Bean类的无参构造器,创建实例对象
那么?我们如何说明出bean是单例的呢?
构建出两份学生对象,执行,发现两个对象的内存地址相同,内存中只有一份
如何使它成为多例的呢?那么则需要在配置文件中添加scope="prototype"该属性即可!
scope="prototype" 原型模式(N个对象):真正使用时才会创建,每获取一次,都会创建不同对象
scope="singleton" 单例模式:容器初始化时需要使用name建,每次获取的都是同一个对象,默认值
使用Spring通过getter访问器实现了对属性赋值,这种做法被称为设值注入。除此之外Spring还提供了通过构造方法赋值的能力,成为构造注入。
下面我们通过一个例子来深入了解一下
首先创建一个Car类
package cn.entity; public class Car { private String color; private String brand; public String toString() { return "Car [color=" + color + "]"; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } }
再书写Student类
package cn.entity; public class Student { private String name; private String age; private Car car; public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", myCar=" +car + "]"; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
1.1设值注入(set方法注入):本质上是调用了Bean的setXXX()进行值的注入。分为普通属性和域属性
测试类:
1
2
3
4
5
6
7
8
|
public class Test01 { @Test public void addTest(){ ApplicationContext ctx= new ClassPathXmlApplicationContext( "applicationContext.xml" ); Student student=(Student) ctx.getBean( "stu" ); System.out.println(student); } |
实现效果:
三、集合属性注入[List、Set、Map]
package cn.entity; import java.util.List; import java.util.Map; import java.util.Set; public class CollectionBean { private List<String> list; private Set<String> set; private Map<String,String> map; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Map<String, String> getMap() { return map; } public void setMap(Map<String, String> map) { this.map = map; } }
applicationContext.xml配置文件书写
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean id="stu" class="cn.entity.Student" scope="prototype"> <property name="color" value="红色"></property> </bean> <bean id="cars" class="cn.entity.Car" scope="prototype"> <property name="color" value="红色"></property> </bean> <bean id="stu1" class="cn.entity.Student" scope="prototype"> <property name="name" value="章撒"></property> <property name="age" value="12"></property> <property name="car" value="cars"></property> </bean> <bean id="car" class="cn.entity.Car"> <property name="color" value="红色"></property> </bean> <bean id="stu2" class="cn.entity.Student"> <property name="name" value="张三"></property> <property name="age" value="18"></property> <property name="car" ref="car"></property> </bean> <bean id="stu3" class="cn.entity.Student" p:name="李四" p:age="13" p:car-ref="car"/> <bean id="list" class="cn.entity.CollectionBean"> <property name="list"> <list> <value>张三</value> <value>李四</value> </list> </property> </bean> <bean id="set" class="cn.entity.CollectionBean"> <property name="set"> <set> <value>张三1</value> <value>李四1</value> </set> </property> </bean> <bean id="map" class="cn.entity.CollectionBean"> <property name="map"> <map> <entry key="dq"> <value>张三2</value> </entry> <entry key="eq"> <value>李四2</value> </entry> </map> </property> </bean> </beans>
测试类
package cn.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.entity.CollectionBean; import cn.entity.HappyService; import cn.entity.Student; public class MyTest { public void listTest(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); CollectionBean bean=(CollectionBean)ctx.getBean("list"); System.out.println(bean.getList()); } @Test public void setTest(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); CollectionBean bean=(CollectionBean)ctx.getBean("set"); System.out.println(bean.getSet()); } @Test public void mapTest(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); CollectionBean bean=(CollectionBean)ctx.getBean("map"); System.out.println(bean.getMap()); } }
list()
set()
map()
四、基于注解的DI
注:在项目中添加Spring AOP相关的JAR文件以及xsd约束文件。
由于是基于注解的DI,所以无需再Spring配置文件中进行节点配置,只需配置包扫描器即可!
配置包扫描器用途:
该包下以及子包中的类才可以被Spring扫描,去寻找被注解的类和属性,让Spring容器管理赋值
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 "> 指定包名 <context:component-scan base-package="cn.entitys"></context:component-scan> </beans>
Student类:
指定@Component中的value即可在测试类中的getBean()中植入即可。
@Value为该属性赋值
等价于@Component的注解:
@Component[不分层的情况下]
@Repository() [Dao层]
@Service() [Biz层]
@Controller() [Action类]
@Component(value="stu") public class Student { @Value("呵呵") private String name; @Value("13") private String age; /* * JDK注解 @Resource(name="car2") */ /* * Spring注解 */ @Autowired @Qualifier(value="car2") private Car car; @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", car=" + car + "]"; }
Car类:
@Component(value="car2") public class Car { @Value("黑色") private String color; @Value("奥迪") private String brand; @Override public String toString() { return "Car [color=" + color + ", brand=" + brand + "]"; }
测试类:
public class Test01 { @Test public void addTest(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); Student student=(Student) ctx.getBean("stu"); System.out.println(student); } }
效果展示