1什么是spring框架
Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
其中
- 轻量级是与EJB对比,它依赖资源少,消耗的资源少
- 分层:一站式,每一层都提供了解决方案例如SpringMVC
Sping的核心
spring的核心是控制翻转(IoC)和面向切面(AOP)
Spring有点
方便解耦,简化开发
- Spring就是一个大工厂(容器),可以将所有的对象的创建和依赖关系的维护,交给Spring管理
- Spring工厂就是用于生成Bean的
AOP编程的支持
- Spring提供面向切面编程的支持,可以方便的实现对程序进行权限拦截,运行监控等功能
声明式的事务的支持
- 只需要通过配置就可以完成对事务的支持,无需手动编程
方便程序的测试
- Spring对Junit4支持,可以通过注解方便的测试Spring程序
方便集成各种优秀框架
- Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
降低JavaEE API的使用难度
- Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低
Spring体系结构S
Spring框架是一个分层架构,它包含一些列的功能要素,并被分为大约20个模块,这些模块分为Core Container,Data Access/Integeration,Web ,AOP,Instrumentation和测试部分。 核心容器为:beans,core,context,expression
入门案例:IOC入门
1,导入jar包
4 + 1 : 4个核心(beans、core、context、expression) + 1个依赖(commons-loggins…jar)这些jar包都在一个spring-framework-3.2.0.RELEASE-dist\spring-framework-3.2.0.RELEASE\libs
里面
2,目标类
学习spring之后,将由Spring创建对象实例–> IoC 控制反转(Inverse of Control)
之后需要实例对象时,从spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中
public interface UserService {
public void addUser();
}
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("adduser");
}
}
//测试类
public class TestIoc {
@Test
public void Test2(){
String xmlPath="com/zeroyoung/a_ioc/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
UserService service = (UserService) app.getBean("userService");
service.addUser();
}
}
编写配置文件
位置:任意,开发中一般在classpath下(src)
名称:任意,开发中常用applicationContext.xml
内容:添加schema约束
约束文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\ xsd-config.html
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 配置service
<bean> 配置需要创建的对象
id :用于之后从spring容器获得实例时使用的
class :需要创建实例的全限定类名
-->
<bean id="userService" class="com.zeroyoung.a_ioc.UserServiceImpl" scope="prototype"></bean>
</beans>
入门案例:DI依赖注入
class BookServiceImpl{
//之前开发:接口 = 实现类 (service和dao耦合)
//private BookDao bookDao = new BookDaoImpl();
//spring之后 (解耦:service实现类使用dao接口,不知道具体的实现类)
private BookDao bookDao;
setter方法
}
模拟spring执行过程
创建service实例:BookService bookService = new BookServiceImpl() –>IoC < bean>
创建dao实例:BookDao bookDao = new BookDaoImple() –>IoC
将dao设置给service:bookService.setBookDao(bookDao); –>DI < property>
创建BookService接口和实现类
创建BookDao接口和实现类
将dao和service配置 xml文件
使用api测试
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("save");
}
}
public interface UserService {
public void addUser();
}
public class UserServiceImpl implements UserService{
private BookDao bookDao;
public BookDao getBookDao() {
return bookDao;
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void addUser() {
bookDao.save();
}
}
//测试方法
@Test
public void Test2(){
String xmlPath="com/zeroyoung/b_DI/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
UserService service = (UserService) app.getBean("userService");
service.addUser();
}
编写配置xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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="userService" class="com.zeroyoung.b_DI.UserServiceImpl">
<!-- 依赖注入
property:用于进行属性注入,
name:UserServiceImpl中的属性名字,通过setter去掉set把大写改小写
ref:另一个bean的id的值 的引用
-->
<property name="bookDao" ref="bookDao"></property>
</bean>
<bean id="bookDao" class="com.zeroyoung.b_DI.BookDaoImpl"></bean>
</beans>
装配Bean 基于XML
有三种实例化bean的方式:默认的构造方法,静态工厂,实例工厂。
一、默认的构造方法
配置方式就如我们的上述所示
<bean id="" class="工厂全限定类名" factory-method="静态方法">
二、静态工厂
静态工厂装配bean通常用于spring与其他框架整合
静态工厂:用于生成实例对象, 所有的方法必须是static
public class MyBeanFactory {
public static UserService createService(){
return new UserServiceImpl();
}
}
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("c_static_factory add users");
}
}
//测试
@Test
public void Test2(){
String xmlPath="com/zeroyoung/c_static_factory/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
UserService service = (UserService) app.getBean("myfact");
service.addUser();
}
配置文件:
<bean id="" class="工厂全限定类名" factory-method="静态方法">
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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="myfact" class="com.zeroyoung.c_static_factory.MyBeanFactory"
factory-method="createService"></bean>
</beans>
三、实例工厂
实例工厂:必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。
public class MyBeanFactory {
public UserService createService(){
return new UserServiceImpl();
}
}
public interface UserService {
public void addUser();
}
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("adduser");
}
}
//测试
@Test
public void Test2(){
String xmlPath="com/zeroyoung/c_factory/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
UserService service = (UserService) app.getBean("userService");
service.addUser();
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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="myBeanFactory" class="com.zeroyoung.c_factory.MyBeanFactory"></bean>
<!--
注册工厂类,
在使用工厂类创建一个实例的时候,使用factory-bean指明工厂,然后指明使用的工厂方法factory-method
-->
<bean id="userService" factory-bean="myBeanFactory" factory-method="createService"></bean>
</beans>
Bean的种类
普通bean:之前操作的都是普通bean。 ,spring直接创建A实例,并返回
- FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。
bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。
< bean id=”” class=”FB”> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值
FB fb = new FB();
return fb.getObject();
BeanFactory 和 FactoryBean 对比?
BeanFactory:工厂,用于生成任意bean。
FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产代理。 获得代理对象实例。AOP使用
作用域
作用域的目的是:用于确定spring创建bean实例个数
取值:
singleton 单例,默认值。
见第一个例子
prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。
<bean id="" class="" scope="">
<bean id="userService" class="com.zeroyoung.a_ioc.UserServiceImpl" scope="prototype"></bean>
生命周期
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
9.执行业务处理
10.如果Bean实现 DisposableBean 执行 destroy
11.调用 指定销毁方法 customerDestroy**
实现
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class User implements BeanNameAware ,ApplicationContextAware,InitializingBean ,DisposableBean {
public User() {
System.out.println("1.构造方法执行");
}
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
System.out.println("2 装载属性,调用setter方法");
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void setBeanName(String name) {
System.out.println("3.通过BeanNameAware接口,获得配置文件id属性的内容:" + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("4.通过ApplicationContextAware接口,获得Spring容器," + applicationContext);
}
/** 5 在后处理bean MyBeanPostProcessor.java 处 */
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("6.通过InitializingBean,确定属性设置完成之后执行");
}
public void userInit(){
System.out.println("7.配置init-method执行自定义初始化方法");
}
/** 8 在后处理bean MyBeanPostProcessor.java 处 */
@Override
public void destroy() throws Exception {
System.out.println("9.通过DisposableBean接口,不需要配置的销毁方法");
}
public void userDestroy(){
System.out.println("10.配置destroy-method执行自定义销毁方法");
}
}
配置文件
<?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">
<!-- 5 lifecycle 生命周期
1.构造方法执行
2 装载属性,调用setter方法
3.通过BeanNameAware接口,获得配置文件id属性的内容:lifeUser
4.通过ApplicationContextAware接口,获得Spring容器
5. 实现BeanPostProcessor后处理,初始化前,执行postProcessBeforeInitialization方法
6.通过InitializingBean,确定属性设置完成之后执行
7.配置init-method执行自定义初始化方法
8. 实现BeanPostProcessor后处理,在自定义初始化之后,执行postProcessAfterInitialization方法
// 执行操作
9.通过DisposableBean接口,不需要配置的销毁方法
10.配置destroy-method执行自定义销毁方法
-->
<bean id="lifeUser" class="cn.itcast.d_lifecycle.User" init-method="userInit" destroy-method="userDestroy">
<property name="username" value="jack"></property>
<property name="password" value="1234"></property>
</bean>
<!-- 5.1配置 后处理bean -->
<bean class="cn.itcast.d_lifecycle.MyBeanPostProcessor"></bean>
</beans>
测试:
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("---->" + applicationContext);
User user = (User) applicationContext.getBean("lifeUser");
System.out.println(user); //业务执行
//必须手动执行关闭,才可以进行之后销毁的操作
applicationContext.close();
}
结果
1.构造方法执行
2 装载属性,调用setter方法
3.通过BeanNameAware接口,获得配置文件id属性的内容:lifeUser
4.通过ApplicationContextAware接口,获得Spring容器,
org.springframework.context.support.ClassPathXmlApplicationContext@169d75d:
startup date [Sun Jun 29 23:39:07 CST 2014]; root of context hierarchy
5. 实现BeanPostProcessor后处理,初始化前 : lifeUser,bean实例: cn.itcast.d_lifecycle.User@1c9f789
6.通过InitializingBean,确定属性设置完成之后执行
7.配置init-method执行自定义初始化方法
8. 实现BeanPostProcessor后处理,在自定义初始化之后 : lifeUser
---->org.springframework.context.support.ClassPathXmlApplicationContext@169d75d:
startup date [Sun Jun 29 23:39:07 CST 2014]; root of context hierarchy
cn.itcast.d_lifecycle.User@1c9f789
9.通过DisposableBean接口,不需要配置的销毁方法
10.配置destroy-method执行自定义销毁方法
初始化和销毁
目标方法执行前后执行后,将进行初始化或销毁。
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("adduser");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
配置文件
<!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userService" class="com.zeroyoung.d_lifeCycle.UserServiceImpl"
init-method="myInit" destroy-method="myDestroy"></bean>
测试:
@Test
public void Test2() throws Exception{
String xmlPath="com/zeroyoung/d_lifeCycle/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
UserService service = (UserService) app.getBean("userService");
service.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
app.getClass().getMethod("close").invoke(app);
}
BeanPostProcessor 后处理Bean
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置< bean class=”“>
pring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前方法 : " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("后方法 : " + beanName);
// bean 目标对象
// 生成 jdk 代理
return Proxy.newProxyInstance(
MyBeanPostProcessor.class.getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------开启事务");
//执行目标方法
Object obj = method.invoke(bean, args);
System.out.println("------提交事务");
return obj;
}});
}
}
配置文件
<!-- 将后处理的实现类注册给spring -->
<bean class="com.zeroyung.e_lifecycle.MyBeanPostProcessor"></bean>
后处理bean作用某一个目标类,还是所有目标类?
所有的
如何只作用一个?
通过“参数2”beanName进行控制
属性依赖注入
依赖注入方式:手动装配 和 自动装配
- 手动装配:一般进行配置信息都采用手动
- 基于xml装配:构造方法、setter方法,P命名空间,SpEL注入,集合注入
- 基于注解装配
- 自动装配:struts和spring 整合可以自动装配 ,有如下装配方式
- byType:按类型装配
- byName:按名称装配
- constructor构造装配
- auto: 不确定装配。
构造方法装配
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid, String username) {
super();
this.uid = uid;
this.username = username;
}
public User(String username, Integer age) {
super();
this.username = username;
this.age = age;
}
配置文件:
<!-- 构造方法注入
* <constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
例如:使用名称name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【类型type 和 索引 index】
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
-->
<bean id="userId" class="com.itheima.f_xml.a_constructor.User" >
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
setter方法
使用上一个目标类
<!-- setter注入的方式 -->
<!--
普通值的注入方式:<property name="" value="" ></property>
等效 <property name="" >
<value>值</value>
</property>
引用数据:
<property name="homeAddr" ref="homeId" ></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
<bean id="homeId" class="com.zeroyoung.e_setter.Address">
<property name="addr" value="阜南"></property>
<property name="tel" value="110"></property>
-->
<bean id="person" class="com.zeroyoung.e_setter.Person">
<property name="pname" value="xx" />
<property name="age">
<value>12</value>
</property>
<property name="homeAddr" ref="homeId" ></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
</bean>
<bean id="homeId" class="com.zeroyoung.e_setter.Address">
<property name="addr" value="阜南"></property>
<property name="tel" value="110"></property>
</bean>
<bean id="companyAddrId" class="com.zeroyoung.e_setter.Address">
<property name="addr" value="IBM"></property>
<property name="tel" value="120"></property>
</bean>
P命令空间
对“setter方法注入”进行简化,替换< property name=”属性名”>,而是在
< bean p:属性名=”普通值” p:属性名-ref=”引用值”>
前提:需要添加命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p命名空间注入 -->
<bean id="person" class="com.zeroyoung.e_p.Person"
p:age="11" p:pname="jack"
p:companyAddr-ref="companyId" p:homeAddr-ref="homeId"></bean>
<bean id="homeId" class="com.zeroyoung.e_p.Address"
p:addr="湖北" p:tel="123"></bean>
<bean id="companyId" class="com.zeroyoung.e_p.Address"
p:addr="阜南" p:tel="543"></bean>
</beans>
SpEl注入
对进行统一编程,所有的内容都使用value
< property name=”” value=”#{表达式}”>
- #{123}、#{‘jack’} : 数字、字符串
- #{beanId} :另一个bean引用
- #{beanId.propName} :操作数据
- #{beanId.toString()} :执行方法
- #{T(类).字段|方法} :静态方法或字段
public class Customer {
private String cname = "jack";
private Double pi ;// = Math.PI;
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Double getPi() {
return pi;
}
public void setPi(Double pi) {
this.pi = pi;
}
@Override
public String toString() {
return "Customer [cname=" + cname + ", pi=" + pi + "]";
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!--
<property name="" value="#{表达式}">
#{123}、#{'jack'} : 数字、字符串
#{beanId} :另一个bean引用
#{beanId.propName} :操作数据
#{beanId.toString()} :执行方法
#{T(类).字段|方法} :静态方法或字段
<property name="cname" value="#{'jack'}"></property> 简单数字字符串
<property name="pi" value="#{T(java.lang.Math).PI}"></property> 静态方法
<property name="cname" value="#{'jack'}"></property>
<property name="cname" value="#{customerId.cname.toUpperCase()}"></property>
通过另一个bean,获得属性,调用的方法
<property name="cname" value="#{customerId.cname?.toUpperCase()}"></property>
?. 如果对象不为null,将调用方法
-->
<bean id="customer" class="com.zeroyoung.e_spEL.Customer">
<property name="cname" value="#{customer.cname?.toUpperCase()}"></property>
<property name="pi" value="#{T(java.lang.Math).PI}"></property>
</bean>
</beans>
集合注入
public class Customer {
private String[] arrayData;
private List<String> listData;
private Set<String> setData;
private Map<String, String> mapData;
private Properties propsData;
public String[] getArrayData() {
return arrayData;
}
public void setArrayData(String[] arrayData) {
this.arrayData = arrayData;
}
public List<String> getListData() {
return listData;
}
public void setListData(List<String> listData) {
this.listData = listData;
}
public Set<String> getSetData() {
return setData;
}
public void setSetData(Set<String> setData) {
this.setData = setData;
}
public Map<String, String> getMapData() {
return mapData;
}
public void setMapData(Map<String, String> mapData) {
this.mapData = mapData;
}
public Properties getPropsData() {
return propsData;
}
public void setPropsData(Properties propsData) {
this.propsData = propsData;
}
@Override
public String toString() {
return "CollData [\narrayData=" + Arrays.toString(arrayData) + ", \nlistData=" + listData + ", \nsetData=" + setData + ", \nmapData=" + mapData + ", \npropsData=" + propsData + "\n]";
}
}
配置文件
<!--
集合的注入都是给<property>添加子标签
数组:<array>
List:<list>
Set:<set>
Map:<map> ,map存放k/v 键值对,使用<entry>描述
Properties:<props> <prop key=""></prop> 【】
普通数据:<value>
引用数据:<ref>
-->
<bean id="customer" class="com.zeroyoung.e_w_set.Customer">
<property name="arrayData">
<array>
<value>DS</value>
<value>DZD</value>
<value>屌丝</value>
<value>屌中屌</value>
</array>
</property>
<property name="listData">
<list>
<value>于嵩楠</value>
<value>曾卫</value>
<value>杨煜</value>
<value>曾小贤</value>
</list>
</property>
<property name="setData">
<set>
<value>停封</value>
<value>薄纸</value>
<value>关系</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="jack" value="杰克"></entry>
<entry>
<key><value>rose</value></key>
<value>肉丝</value>
</entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="高富帅">嫐</prop>
<prop key="白富美">嬲</prop>
<prop key="男屌丝">挊</prop>
</props>
</property>
</bean>
装配Bean 基于注解
注解:就是一个类,使用@注解名称
开发中:使用注解 取代 xml配置文件。
1、 @Component取代
2、@Component(“id”) 取代
3、web开发,提供3个@Component注解衍生注解(功能一样)取代
- @Repository :dao层
- @Service:service层
- @Controller:web层
4、依赖注入 ,给私有字段设置,也可以给setter方法设置
普通值:@Value(“”)
引用值:
- 方式1:按照【类型】注入
@Autowired - 方式2:按照【名称】注入1
@Autowired
@Qualifier(“名称”) - 方式3:按照【名称】注入2
@Resource(“名称”)
生命周期:
初始化:@PostConstruct
销毁:@PreDestroy
作用域
@Scope(“prototype”) 多例
注解使用前提,添加命名空间,让spring扫描含有注解类
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="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
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 组件扫描,扫描含有注解的类 -->
<context:component-scan base-package="com.itheima.g_annotation.a_ioc"></context:component-scan>
</beans>
简单例子
public interface UserService {
public void addUser();
}
@Component("userService")//注解相当于<bean id="userService" class=""></bean>
public class UserServiceImpl implements UserService{
public void addUser() {
System.out.println("adduser");
}
}
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="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
http://www.springframework.org/schema/context/spring-context.xsd">
<!--
注解方式注入
-->
<context:component-scan base-package="com.zeroyoung.g_annotation.a_ioc"></context:component-scan>
</beans>
web开发的注入方式:
@Controller("studentAction")//注解这个类id为studentAction
public class StudentAction {
@Autowired//默认类型的,按照类型来
private StudentService service;
public void execute(){
System.out.println("student action");
service.addStudent();
}
}
//接下StudentService
@Service
public class StudentServiceImpl implements StudentService {
//@Autowired //setter的方式注入
//@Qualifier("studentDao") //当默认类型有多重的时候,添加一个名字进行注入
private StudentDao student;
public StudentDao getStudent() {
return student;
}
@Autowired
@Qualifier("studentDao")
public void setStudent(StudentDao student) {
this.student = student;
}
public void addStudent() {
System.out.println("添加了一个学生");
student.save();
}
@PostConstruct//初始化注解
public void init(){
System.out.println("初始化方法");
}
@PreDestroy//销毁注解
public void destroy(){
System.out.println("销毁方法");
}
}
@Repository("studentDao")//注册类型<bean id="studentDao" calss="xxx">
public class StudentDaoImpl implements StudentDao {
public void save() {
System.out.println("save");
}
}
//测试
@Test
public void Test2() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
String xmlPath="com/zeroyoung/g_annotation/b_DI/bean.xml";
ApplicationContext app = new ClassPathXmlApplicationContext(xmlPath);
StudentAction student = (StudentAction) app.getBean("studentAction");
student.execute();
app.getClass().getMethod("close").invoke(app);
}
结果: