初识Spring与Spring-IOC容器
一、Spring框架的概念
- Spring是一款企业级级开发的开源框架
- Spring提供IOC容器和AOP框架:
- IOC解决了对象的创建以及对象管理,同时解决对象与对象之间的依赖
- AOP解决的是一些公共业务逻辑(事物管理、日志收集等)
- Spring是一个“粘合剂”
- 采用Spring去集成第三方框架或者组件(MyBatis/Redis/RabbitMQ/Hibernate…),集成原理还是基于IOC容器
二、Spring框架组件
- 数据访问相关组件(Data Access):
- Spring JDBC/Spring ORM/Spring OXM
- Web应用相关组件(Web):
- Spring Web、Spring MVC(重点)、Spring Websocket…
- AOP(面向切面编程)、Aspects(切面)
- 核心容器组件(Core Container):
- Beans(Bean相关内容:BeanFactory)
- Context(Spring配置的上下文 ApplicationContext)
- Core
- SpEL(Spring的EL表达式)
- 测试组件(Spring-test):
- mock(模拟)测试、Random Port(随机端口测试)、TestContext Framework(测试上下文框架)
三、集成Spring框架
-
方法:在项目的pom中添加spring-context依赖,通过Maven的依赖传递将Spring其他核心组件的jar包也一起依赖进项目(aop/beans/core/spel),Spring开源的源代码存放在GitHub上
-
代码:
<!--依赖Spring相关jar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.1.RELEASE</version> </dependency>
四、BeanFactory和ApplicationContext
ApplicationContext是BeanFactory的子类,它除了拥有BeanFactory的功能外,还包含有国际化、资源加载、事件传递等等
五、Bean实例化的模拟
思路
- 读取xml,解析xml配置(dom4j解析)
- 获取<bean id="" class="" />标签,将bean标签的属性封装到对象中
- 将解析后的<bean>标签的对象存入集合中
- 遍历解析后的Bean标签(id, class)集合,同时利用反射机制创建对象,并将id和对象存入map中
- 编写一个getBean(id)的方法获取bean实例化后的对象
代码实现
-
编写一个BeanFactory,暴露一个getBean接口
/** * 模拟Bean工程提供获取Bean的方法 */ public interface BeanFactory { public Object getBean(String id); }
-
编写BeanFactory的实现类MyClassPathXmlApplicationContext()
/** * 模拟的是一个ApplicationContext上下文容器 */ public class MyClassPathXmlApplicationContext implements BeanFactory { private Map<String, Object> beans = new HashMap<>();// 实例化后的对象放入map private List<MyBean> myBeans;// 存放已读取bean 配置信息 }
-
编写一个构造器,传入xml配置文件,调用解析方法进行xml读取、解析,调用实例化对象的方法去实例化对象(应用反射机制)
// 构造器,传入xml配置文件名 public MyClassPathXmlApplicationContext(String fileName) { this.readBeansXml(fileName);// 读取并解析配置文件 this.insranceBeans(); // 实例化bean }
-
读取、解析xml配置文件,将bean标签内容存入集合的MyBean对象中(bean metadata)
/** * 读取 并解析xml 配置文件 * @param fileName */ private void readBeansXml(String fileName) { URL url=this.getClass().getClassLoader().getResource(fileName); // 判断xml配置文件是否存在 if (url == null) { System.out.println("资源文件未找到!"); return; } // 解析xml配置文件 SAXReader saxReader=new SAXReader();// 创建saxReader 对象 Document doc= null; try { doc = saxReader.read(url); } catch (DocumentException e) { e.printStackTrace(); // 打印异常的堆栈信息 return; } Map<String, String> map = new HashMap<>(); // 一定要加泛型 map.put("my", "http://www.springframework.org/schema/beans"); //将xml命名空间放入map XPath xPath= doc.createXPath("//my:bean");//定义查找路径 xPath.setNamespaceURIs(map); List<Element> elements = xPath.selectNodes(doc); if (CollectionUtils.isEmpty(elements)) { return; } myBeans = new ArrayList<>(); for(Element element : elements){ //System.out.println(element.attributeValue("id")+element.attributeValue("class")); MyBean myBean = new MyBean(element.attributeValue("id"), element.attributeValue("class")); myBeans.add(mytBean); } }
-
遍历bean的元数据信息(MyBean集合)信息,利用反射实例化对象,同时存储到map中
/** * 实例化bean 对象 */ private void insranceBeans() { // 先判断<bean>标签集合是否有值 if (CollectionUtils.isEmpty(myBeans)) { return; } // 遍历<bean>标签,同时利用反射机制生成对象,并将对象存入map中,其中key为bean对象的id,value是对象 for(MyBean myBean: myBeans){ try { beans.put(myBean.getId(), Class.forName(myBean.getClazz()).newInstance()); } catch (Exception e) { continue; } } }
-
重写getBean方法,从map中返回bean的实例化后的对象
/** * 根据id 名获取bean */ @Override public Object getBean(String id) { return beans.get(id); }
六、IOC容器加载多个配置文件
-
第一种:启动ApplicationContext上下文容器时,允许加载多个配置文件
-
第二种:用某一个公共的配置文件,把其他配置文件通过<import resource="" />导入进来
<bean id="helloService" class="com.myspring.service.HelloService" /> <import resource="controller.xml" /> <import resource="service.xml" /> <import resource="dao.xml" />
public class AppTest { @Test public void testMultiXml() { // 启动IOC容器(加载配置文件生成ApplicationContext) ApplicationContext ac = new ClassPathXmlApplicationContext("controller.xml", "dao.xml", "service.xml"); // 获取Bean对象 UserController userController = ac.getBean("userController", UserController.class); UserService userService = ac.getBean("userService", UserService.class); UserDao userDao = ac.getBean("userDao", UserDao.class); // 调用Bean方法 userController.show(); userService.add(); userDao.save(); } @Test public void testSingleXml() { // 启动IOC容器(加载配置文件生成ApplicationContext) ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); // 获取Bean对象 UserController userController = ac.getBean("userController", UserController.class); UserService userService = ac.getBean("userService", UserService.class); UserDao userDao = ac.getBean("userDao", UserDao.class); // 调用Bean方法 userController.show(); userService.add(); userDao.save(); } }
七、Bean的实例化方式
1. 构造器实例化
- 通过默认构造器创建 空构造方法必须存在 否则创建失败(简单|重要)
<bean id="userServiceImpl" class="com.myspring.service.impl.UserServiceImpl" ></bean>
2. 静态工厂实例化
- 编写一个工厂类,同时编写一个静态方法,该方法返回需要创建的对象
/**
* 静态工厂实例化Bean
*/
public class StaticFactory {
/**
* 编写一个静态方法,同时返回一个实例化对象
* @return
*/
public static UserService createUserService(){
return new UserService();
}
}
<?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,配置的class指向工厂类,添加factory-method属性指向创建对象的静态方法-->
<bean id="userService" class="com.myspring.factory.StaticFactory" factory-method="createUserService" />
</beans>
3. 实例化工厂方法
- 编写一个工厂类,同时编写一个非静态方法,该方法返回需要创建的对象,在配置时,需要先实例化工厂bean
/**
* 实例化工厂创建Bean对象
*/
public class InstanceFactory {
/**
* 此方法不需要静态化
* @return
*/
public UserService createUserService() {
return new UserService();
}
}
<?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对象-->
<bean id="instanceFactory" class="com.myspring.factory.InstanceFactory" /> <!--工厂bean-->
<!--实例化UserService Bean-->
<bean id="userService" factory-bean="instanceFactory" factory-method="createUserService" />
</beans>
八、对象依赖与注入
IOC本质问题 ***
-
IOC:控制反转,就是由原来主动创建对象改成交给Spring创建对象
// 主动创建 public class UserController { private UserService userService = new UserService(); } // 交由第三方创建再传入 public class UserController { private UserService userService ; public UserController(UserService userService) { this.userService = userService; } }
依赖注入(DI) ***
- 依赖:对象与对象之间的关系,注入由第三方(Spring)在实例化对象时进行注入。
- 因此DI是IOC的另外一种表达方式,换个说法:IOC是DI的理论基础
- 注入:可以简单理解为赋值
依赖注入的方式 ***
1. 构造器注入 **
通过构造器传参,将对象注入给对应的属性
-
注入对象
-
例子:
// 编写一个NoteDao,里面有个findNote()方法 public class NoteDao { public void find() { System.out.println("查询笔记。。。"); } }
// 编写一个NoteService,包含NoteDao属性,编写一个构造器,把NoteDao注入进来 public class NoteService { private NoteDao noteDao; public NoteService() {} // 创建一个构造器方法 public NoteService(NoteDao noteDao) { System.out.println("构造器注入。。。"); this.noteDao = noteDao; } /** * 查找笔记 */ public void findNote() { noteDao.find(); } }
<!--实例化NoteDao对象--> <bean id="noteDao" class="com.myspring.dao.NoteDao"/> <!--实例化NoteService--> <bean id="noteService" class="com.myspring.service.NoteService"> <!--给NoteService(NoteDao noteDao)构造器注入NoteDao的对象--> <constructor-arg name="noteDao" ref="noteDao"/> </bean>
/** * 测试 */ public class NoteServiceTest { private ApplicationContext ac; @Before public void initAc() { // 启动IOC容器 ac = new ClassPathXmlApplicationContext("application-note.xml"); } @Test public void testFindNote() { // 获取UserService对象 NoteService noteService = ac.getBean("noteService", NoteService.class); noteService.findNote(); } }
-
-
注入基本类型
public class Note { private Integer id; private String content; private Integer userId; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Note() { } public Note(Integer id, String content, Integer userId) { this.id = id; this.content = content; this.userId = userId; } }
<!--实例化Note对象--> <bean id="note" class="com.myspring.model.Note"> <!--其中name为参数名,value参数值,index为参数下标--> <constructor-arg name="id" value="1" index="0" /> <constructor-arg name="userId" value="123" index="2"/> <constructor-arg name="content" value="今天是个好天气" index="1"/> </bean>
-
简化配置:通过引入c标签,简化配置构造器注入
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:c="http://www.springframework.org/schema/c" 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"> <!--实例化NoteDao对象--> <bean id="noteDao" class="com.myspring.dao.NoteDao"/> <!--实例化NoteService--> <bean id="noteService" class="com.myspring.service.NoteService" c:noteDao-ref="noteDao" /> <!--给NoteService(NoteDao noteDao)构造器注入NoteDao的对象 <constructor-arg name="noteDao" ref="noteDao"/> </bean>--> <!--实例化Note对象--> <bean id="note" class="com.myspring.model.Note" c:id="1" c:userId="123" c:content="今天是个好天气" /> <!--其中name为参数名,value参数值,index为参数下标 <constructor-arg name="id" value="1" index="0" /> <constructor-arg name="userId" value="123" index="2"/> <constructor-arg name="content" value="今天是个好天气" index="1"/> </bean>--> </beans>
2. setter注入 ***
就是编写一个属性的set方法,然后进行依赖注入
-
注入对象
public class UserDao { public void save() { System.out.println("Save User..."); } }
public class UserService { private UserDao userDao; /** * 编写一个添加用户的方法 */ public void addUser() { userDao.save(); } /** * UserDao的set方法 * @param userDao */ public void setUserDao(UserDao userDao) { System.out.println("setter注入UserDao对象"); this.userDao = userDao; } }
<?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唯一标记这个bean,class属性代表是这个bean的类--> <bean id="userService" class="com.myspring.service.UserService" > <!--依赖注入UserDao对象--> <property name="userDao" ref="userDao" /> </bean> <!--实例化UserDao对象--> <bean id="userDao" class="com.myspring.dao.UserDao" /> </beans>
@Test public void testAddUser() { // 启动IOC容器 ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); // 获取UserService对象 UserService userService = ac.getBean("userService", UserService.class); // 调用addUser()方法 userService.addUser(); }
-
注入基本类型
package com.myspring.model; public class User { private Integer id; private String userName; private String password; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
<!--实例化User对象--> <bean id="user" class="com.myspring.model.User"> <!--基本类型注入--> <property name="id" value="2" /> <property name="userName" value="banzhang"/> <property name="password" value="1234555"/> </bean>
@Test public void testAddUser2() { // 启动IOC容器 ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); // 获取UserService对象 UserService userService = ac.getBean("userService", UserService.class); // 调用addUser()方法 User user = ac.getBean("user", User.class); userService.addUser(user); }
-
简化set注入配置:通过引入p标签简化
<?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唯一标记这个bean,class属性代表是这个bean的类--> <bean id="userService" class="com.myspring.service.UserService" p:userDao-ref="userDao" /> <!--依赖注入UserDao对象 <property name="userDao" ref="userDao" /> </bean>--> <!--实例化UserDao对象--> <bean id="userDao" class="com.myspring.dao.UserDao" /> <!--实例化User对象--> <bean id="user" class="com.myspring.model.User" p:id="2" p:password="122345" p:userName="banzhang" /> <!--基本类型注入 <property name="id" value="2" /> <property name="userName" value="banzhang"/> <property name="password" value="1234555"/> </bean>--> </beans>
3. 静态工厂注入(不常用)
4. 实例化工厂注入(不常用)
九、List、Set、Map、Properties、空字符、null注入
看代码:
public class User {
private Integer id;
private String userName;
private String password;
private List<String> noddles;
private Set<String> cookies;
private Map<String, String> views;
private Properties games;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getNoddles() {
return noddles;
}
public void setNoddles(List<String> noddles) {
this.noddles = noddles;
}
public Set<String> getCookies() {
return cookies;
}
public void setCookies(Set<String> cookies) {
this.cookies = cookies;
}
public Map<String, String> getViews() {
return views;
}
public void setViews(Map<String, String> views) {
this.views = views;
}
public Properties getGames() {
return games;
}
public void setGames(Properties games) {
this.games = games;
}
}
<bean id="user" class="com.myspring.model.User">
<property name="id" value="0" />
<property name="userName" value=""/> <!--空字符串-->
<property name="password"> <!--null值-->
<null />
</property>
<property name="noddles">
<list>
<value>河南烩面</value>
<value>臊子面</value>
<value>担担面</value>
<value>兰州拉面</value>
</list>
</property>
<property name="cookies">
<set>
<value>曲奇</value>
<value>奥利奥</value>
<value>闲趣</value>
</set>
</property>
<property name="views">
<map>
<entry>
<key><value>上海</value></key>
<value>城隍庙</value>
</entry>
<entry>
<key><value>北京</value></key>
<value>四合院</value>
</entry>
<entry>
<key><value>西安</value></key>
<value>大雁塔</value>
</entry>
</map>
</property>
<property name="games">
<props>
<prop key="暴雪">暗黑破坏神</prop>
<prop key="育碧">刺客信条</prop>
<prop key="任天堂">马里奥制造</prop>
</props>
</property>
</bean>
十、自动装配(装载)
概念
- 利用注解方式自动装配bean的依赖关系,达到简化依赖注入的操作
- 使用时必须要开启注解驱动<context:annotation-config />
1. @Autowired
-
它是Spring框架注解
-
根据类型查询bean(byType)
-
默认情况下依赖的bean必须要存在,否则会提示找不到该bean异常
- 因为required属性控制了依赖的bean是否必须存在,默认是@Autowired(required=true)
-
@Autowired既可以设置在属性上,也可以设置在setter方法上
public class UserController { @Autowired // 推荐,其中required属性代表bean是否必须存在,默认为true private UserService userService; public void show(User user) { System.out.println("调用控制层方法。。"); userService.addUser(user); } // @Autowired // 不推荐 // public void setUserService(UserService userService) { // this.userService = userService; // } }
<!--开启自动装载注入--> <context:annotation-config /> <bean name="userController" class="com.myspring.controller.UserController" />
2. @Resource
- 它是Jdk的注解
- 如果没有指定name(@Resource),先根据name(byName)查询,查询不到再根据类型(byType)匹配,比如
@Resource
private UserService userService;
- 如果指定name属性,那么只会根据name进行查询(byName)
@Resource(name = "userService")
private UserService userService;
3. @Qualifier
十一、Spring IOC 扫描器——扫描 + 注解实例化Bean
1. 添加扫描配置
-
在配置文件中添加:<context:component-scan base-package=" "/>进行扫描配置,其中base-package代表扫描的包路径
-
不需要开启注解驱动<context:annotation-config />
<?xml version="1.0" encoding="UTF-8"?> <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 https://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描注解,其中base-package属性代表扫描的package--> <context:component-scan base-package="com.myspring"/> </beans>
2. 注解标记实例类
- @Component注解,如果不能区分这个类是属于那一层,那么当做一个普通组件交给Spring管理
- @Controller注解,标记这个类是控制层
- @Service注解,标记这个类是业务逻辑层
- @Repository注解,标记这个类是数据访问逻辑层
十二、Spring配置Bean的方式
第一种:声明式配置
- 通过在xml中配置bean标签进行实例化
- 包括构 造器实例化、静态工厂和实例化工厂实例化
第二种:Spring IOC 扫描器
- 扫描 + 注解,通过component-scan进行扫描包 + 组件(@Component)注解
第三种:通过注解方式配置Bean
-
@Configuration(类注解) + @Bean(方法)
-
首先要也要有扫描@Configuration注解的类
-
通过@Configuration标记的类相当于<beans ></beans>
-
@Bean相当于<bean id=“默认是方法名称” class=“返回类型” />
-
举例:
-
第一步:编写HelloController和HelloService类
@Controller // 标记这个controller交给Spring管理 public class UserController { @Autowired private UserService userService; public void show(User user) { System.out.println("调用控制层方法。。"); userService.addUser(user); } }
public class HelloService { public void say() { System.out.println("Hello Java Config...."); } }
-
第二步:配置一个HelloService的Bean
@Configuration public class HelloServiceConfiguration { @Bean// 默认使用方法名作为bean的名称 public HelloService helloService() { return new HelloService(); } }
-
第三步:添加扫描
<?xml version="1.0" encoding="UTF-8"?> <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 https://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描注解,其中base-package属性代表扫描的package--> <context:component-scan base-package="com.myspring"/> </beans>
-
十三、Spring Bean 的作用域
作用域分类 | 名称 | 说明 |
---|---|---|
单例 | singleton | 在SpringIOC容器中,Bean创建好之后会存在 单例Bean的缓存池中,获取Bean时从池中直接 拿取即可,性能高 |
原型 | prototype | 不会缓存,每次获取每次创建 |
Web应用 | request、session、application、webSocket | 必须要有 web 环境支持,并配置相应的容器 监听器或拦截器从而能应用这些作用域 |
-
默认是单例 singleton
-
即在SpringIOC容器中,Bean创建好之后会存在单例Bean的缓存池中,获取Bean时从池中直接拿取即可,性能高
-
注意:lazy-init 是懒加载,如果等于 true 时作用是指 Spring 容器启动的时候不会去实例化这个 bean,而是在程序调用时才去实例化。默认是 false 即 Spring 容器启动时实例化
-
容器在启动的情况下就实例化所有 singleton 的 bean 对象 的好处:
- 提前发现潜在的配置问题
- Bean 对象存在于缓存中,使用时不用再去实例化 bean,加快程序运行效率
-
一般来说对于无状态或状态不可改变的 对象适合使用单例模式
-
-
原型 prototype,不会缓存,每次获取每次创建
-
通过 scope=“prototype” 设置 bean 的类型 ,每次向 Spring 容器请求获取Bean 都返回一个全新的 Bean,相对于 “singleton” 来说就是不缓存 Bean,每次都是一个根据 Bean 定义创建的全新 Bean
-
-
Web应用中存在作用域:request、session、application、webSocket
十四、Bean 的生命周期
(1)定义
- 声明式配置
- 扫描器 + 注解
- 编程式(java config)@Configuration + @Bean
(2)初始化
-
启动容器,生成上下文对象ApplicationContext
- (FileSystemXmlApplicationContex、ClassPathXmlApplicationContex、AnnotationConfigApplicationContext)
-
可以再通过 init-method 添加初始化代码
(3)使用
- 调用BeanFactory中的getBean方法获取Bean,再调用Bean的方法
(4)销毁
- 可以通过 destroy-method 添加销毁代码
- 可以通过调用AbstractApplicationContext的close()方法进行销毁
Bean初始化的时序图
package com.myspring.model;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
public class User implements InitializingBean, BeanNameAware {
private String userId;
private String userName;
private String email;
private String hometown;
private String job;
private String beanName;
public User() {
System.out.println("**************第一步: 调用Bean的默认构造方法**************");
this.userId = "bean1: myspring001";
System.out.println("bean1的值: " + this);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("bean2的值: " + this);
System.out.println("**************第三步: 检查Bean是否实现了InitializingBean接口**************");
this.userName = "bean3: 隔壁老王";
this.email = "bean3: aaa@qq.com";
System.out.println("bean3的值: " + this);
}
public void init() {
System.out.println("**************第四步: 检查配置文件中是否指定了init-method方法**************");
this.hometown = "bean3: 上海";
System.out.println("bean4: " + this);
}
public void destroy () {
System.out.println("**************服务停止**************");
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
System.out.println("**************第二步: Bean的配置文件中是否注入了bean的属性值**************");
System.out.println("bean11的值: " + this);
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getHometown() {
return hometown;
}
public void setHometown(String hometown) {
this.hometown = hometown;
}
public String getBeanName() {
return beanName;
}
@Override
public void setBeanName(String beanName) {
System.out.println("**********设置bean的名称**********");
this.beanName = "userBeanName";
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", email="
+ email + ", hometown=" + hometown + ", job=" + job
+ ", beanName=" + beanName + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--声明式配置
<bean id="userService" class="com.myspring.service.UserService" destroy-method="destroy" init-method="initUserService" />
-->
<bean id="user" class="com.myspring.model.User" init-method="init" destroy-method="destroy">
<property name="userName" value="abcd" />
</bean>
</beans>
上一篇: Spring Boot框架搭建