jar 下载地址
https://repo.spring.io/libs-release-local/org/springframework/
IOC Inversion of Control 控制反转
应用本身不负责依赖对象的创建和维护。依赖对象的创建和维护是由外部容器负责,这样控制权就由应用程序转移到了外部容器(Spring),控制权的转移就是所谓的反转。
DI dependency injection 依赖注入
在运行期间,由外部容器动态的将对象注入到组件中。
一、Scope
<bean id="userAction" class="com.hap.action.UserAction" scope="prototype"/>
singleton 单例 只能产生一个对象。 默认单例模式。
prototype 多例 每一次都会获取新的对象。
Action 是单例还是多例
Spring 默认是单例
二、Spring 实例化Bean的三种形式
1. 第一种: 使用默认无参构造器(用的最多的)
<bean id="userAction" class="com.hap.action.UserAction" scope="prototype">
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserAction action = (UserAction) applicationContext.getBean("userActioin");
action.addUser();
2. 第二种: 静态工厂 方法
<bean id="userAction" class="com.hap.action.UserActionFactory" factory-method="getBean"/>
public class UserAction {
public String addUser(){
System.out.println("-----------");
return "/index.jsp";
}
}
public class UserActionFactory {
public static UserAction getBean(){
return new UserAction();
}
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserAction action = (UserAction) applicationContext.getBean("userAction");
action.addUser();
}
3. 第三种:实例工厂 方法
<bean id="beanFactory" class="com.hap.action.BeanFactory"/>
<bean id="bean" factory-bean="beanFactory" factory-method="getBean"/>
public class Bean { }
public class BeanFactory {
public Bean getBean(){
return new Bean();
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Bean bean = (Bean) applicationContext.getBean("bean");
System.out.println(bean);
}
三、 Bean的属性注入(xml)
1.set方法注入
a.注入类
<!--注入类-->
<bean id="userAction" class="com.hap.action.UserAction" scope="prototype">
<property name="userService" ref="userService"></property>
</bean>
<bean id="userService" class="com.hap.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
<property name="roleDao" ref="roleDao"/>
</bean>
<bean id="userDao" class="com.hap.dao.impl.UserDaoImpl"></bean>
<bean id="roleDao" class="com.hap.dao.impl.RoleDaoImpl"></bean>
public class UserAction {
private UserService userService; //注入 IOC 控制反转 DI 依赖注入
public void setUserService(UserService userService) {
this.userService = userService;
}
public String addUser(){
userService.addUser();
return "/index.jsp";
}
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserAction action = (UserAction) applicationContext.getBean("userAction");
action.addUser();
}
b.注入简单类型
<!--注入简单类型-->
<bean id="user" class="com.hap.beans.User">
<property name="id" value="18"/>
<property name="name" value="张三"/>
</bean>
public class User {
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
@Override
public String toString() {
return "User{" +"id=" + id +", name='" + name + '\'' +'}';
}
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user.toString());
}
集合属性的注入(java.utils)
Spring对java.utils中常用集合对象提供了专门的配置标签
java.utils中常用的集合 (List、Set、Map、Properties)
c.注入集合
<!--注入集合-->
<bean id="collectionBean" class="com.hap.action.CollectionBean">
<!-- 注入list 基本数据类型 -->
<property name="carBrand">
<list>
<value>宝马</value>
<value>奔驰</value>
<value>奥迪</value>
</list>
</property>
<!-- 注入 Set 复杂数据类型 -->
<property name="cars">
<set>
<ref bean="car"/>
<ref bean="car2"/>
</set>
</property>
<!-- 注入Map -->
<property name="carModel">
<map>
<entry key="宝马" value="X5"/>
<entry key="奔驰" value="GLC"/>
<entry key="奥迪" value="Q7"/>
</map>
</property>
<!-- 注入property -->
<property name="users">
<props>
<prop key="鲁智深">花和尚</prop>
<prop key="武松">行者</prop>
</props>
</property>
</bean>
<bean id="car" class="com.hap.beans.Car">
<constructor-arg index="0" value="宝马"/>
<constructor-arg index="1" value="white"/>
</bean>
<bean id="car2" class="com.hap.beans.Car">
<constructor-arg index="0" value="奥迪"/>
<constructor-arg index="1" value="white"/>
</bean>
// 集合Bean ,向Bean中注入 List 、 Set 、Map 、Properties 对应数据
public class CollectionBean {
private List<String> carBrand;
private Set<Car> cars;
private Map<String, String> carModel;
private Properties users;
public void setCarBrand(List<String> carBrand) {
this.carBrand = carBrand;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
public void setCarModel(Map<String, String> carModel) {
this.carModel = carModel;
}
public void setUsers(Properties users) {
this.users = users;
}
@Override
public String toString() {
return "CollectionBean{" + "carBrand=" + carBrand + ", cars=" + cars + ", carModel=" + carModel + ", users=" + users + '}';
}
}
public class Car {
private String name;
private String color;
public Car(){}
public Car(String name, String color) {
super();
this.name = name;
this.color = color;
}
@Override
public String toString() {
return "Car [name=" + name + ", color=" + color + "]";
}
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
System.out.println(collectionBean.toString());
}
2. 构造方法注入
<bean id="user" class="com.hap.beans.User">
<constructor-arg name="id" value="10"/>
<constructor-arg name="name" value="张三"/>
</bean>
<!--可以通过index或者Type注入-->
<bean id="user" class="com.hap.beans.User">
<constructor-arg index="0" type="int" value="10"/>
<constructor-arg index="1" type="java.lang.String" value="张三"/>
</bean>
<!--构造方法 参数为对象 注入-->
<bean id="userAction" class="com.hap.action.UserAction" scope="prototype">
<constructor-arg name="userService" ref="userService"/>
</bean>
public class User {
private int id;
private String name;
public User() {}
public User(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user.toString());
}
private UserService userService; //注入 IOC 控制反转 DI 依赖注入
public UserAction() {}
public UserAction(UserService userService) {
this.userService = userService;
}
public String addUser(){
userService.addUser();
return "/index.jsp";
}
@Test
public void testScope(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
UserAction action = (UserAction) applicationContext.getBean("userAction");
action.addUser();
}
四、 自动注入
byName 通过名称匹配
byType 通过类型匹配,只能提供一个匹配
constructor 通过构造方法匹配
<!-- 配置该注解 支持 @Autowired @Resource @PreDestroy @PostConstruct -->
<context:annotation-config/>
<!-- Spring会自动扫描 配置 package 下所有使用spring 注解的类 -->
<context:component-scan base-package="com.hap"/>
Spring3提供了3个功能基本和@Component等效的注解
@Respository 用于对Dao 实现类进行注解
@Service 用于对service实现类进行注解
@Controller 用于对Controller实现类进行注解
- @Autowired 默认按照byType。如果有多个匹配的bean,则先通过byName匹配,如果找不到对应的byName,则抛异常。
- @Qualifier 指定id进行注入。
- @Resource 默认按照 byName,如果没有匹配的name,那么按照byType,如果找到两个ByType,则抛异常。
根据name属性进行指定id注入。
@Component 组件,创建bean,通过注解
@Repository 标在dao层
@Service 在service层
@Controller 控制 在控制层
在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常
五、 配置类
Spring3.0引入javaconfig思想,使用一个java类 作为 Spring的配置文件
@Configuration 指定POJO类为Spring提供Bean定义信息
@Bean 提供一个Bean定义信息
以一个Java类 作为配置文件,通过@Bean生成某个方法, 就是一个Bean工厂
@Configuration
// 该类是一个配置类
public class BeanConfig {
@Bean(name = "employee")
// 相当于 实例工厂方法,对employee这个bean 进行初始化
public Employee createEmployee() {
Employee employee = new Employee();
employee.setCompany("Sun");
employee.setName("小王");
return employee;
}
}
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
// 加载配置Bean
annotationConfigApplicationContext.register(BeanConfig.class);
annotationConfigApplicationContext.refresh();