尤其是注解版本,都看懂了没有,你们最好都建立maven工程,不要建单独的java项目,这个项目建好了之后说一下,
直接把pom文件copy过来,pom文件里面不是有依赖信息吗,你们都不要去写了,写比较浪费时间,那么这个时候我就直接
讲一下,一种场景,在这里我们首先先讲第一种方式,手写XML版本的,XML版本是最简单的,而且是最好理解的,首先我们
看看效果,看什么效果呢,你们千万不要把代码记下来,那都不重要,而是要记他的过程和原理,这个话我再说一遍,在这里
我们看个例子,看个什么例子呢,UserService userService = (UserService) app.getBean("userServiceImpl");
我们是不是写过这个代码,干嘛用的你们想想,记住这是原生的,不是我写的,这是原生的,是不是获取bean对象,IOC你们
都懂不懂,什么是IOC,这个了不了解,都了解吧,IOC就是把bean与bean之间的关系交给第三方容器进行管理,那么这个时候我说一下,
任何关于bean的初始化对象,全部不是自己new的,我这里就不去过多讲IOC,全部加入Spring,为什么有容器的概念,他存放了对象的
一个过程,不用自己去new了,在容器里面有很多对象,如果你不new的话,Spring怎么知道去new这个对象呢,在这里你们就会学到反射
机制,你们有没有看过原理是怎么做的吗,有没有谁能知道,SpringIOC使用了反射机制,我们大体说一下步骤是怎么做的呢
<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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 比如我们在这里写一个bean对象
xml方式注入bean,他怎么用呢
首先我来讲一下bean的一个配置,id表示定义的唯一的一个id,
这个class写什么,类的完整路径,为什么写完整路径呢,比如我们的userService
我直接写com.learn.service.impl.UserServiceImpl,记得是要写完整路径
是不是这样子,你们只要一看到类的完整路径的时候,其他都不用想,肯定是用反射,他肯定是通过反射去初始化类的对象
我们今天主要是讲注入容器的过程
-->
<bean id="userService" class="com.learn.service.impl.UserServiceImpl">
<!-- 你们想注入属性的时候
username,然后写值
-->
<!-- <property name="username">1234</property> -->
</beans>
package com.learn.service;
public interface UserService {
public void add();
}
package com.learn.service.impl;
import com.learn.annotation.ExtResource;
import com.learn.annotation.ExtService;
import com.learn.service.OrderService;
import com.learn.service.UserService;
//将该类注入到spring容器里面
/**
* 就是UserServiceImpl这样一个bean
* 我们现在使用的都是自定义注解
* 只要是加上我们这个自定义注解之后
* 那么这个时候他就会去注入bean的
* 就会自动去获取bean
*
*
* @author Leon.Sun
*
*/
@ExtService
public class UserServiceImpl implements UserService {
private UserServiceImpl() {
/**
* 我去打印这样一段话
* 反射肯定是需要走构造函数的
*
*/
System.out.println("无参构造函数初始化......反射技术");
}
// 从Spring容器中读取bean
/**
* 为什我加上@ExtResource这么一个注解
* 就可以获取orderServiceImpl这么一个对象
* 是不是这样的
* 这就是我要讲的原理的过程
* 我把这个@ExtService注解给注掉
* @ExtResource
* private OrderService orderServiceImpl;
* 这里还能取到吗
* 还能不能取到
* 能不能取到这个对象
* 能不能取到OrderService
* 肯定取不到
* 为什么呢
* 我们运行一遍
* java.lang.NullPointerException
* 是不是报了一个空指针
* 我把@ExtService注解一加上去
* 一加上去就可以运行了
* 看到效果没有
* 我来讲一下整个实现原理
* 我今天还来讲一个知识
* 什么知识呢
* XML版本的
* xml版本的可能稍微简单点
*
*
*
*/
@ExtResource
private OrderService orderServiceImpl;
public void add() {
/**
* 这里会调用addOrder()
* 是不是这样的
*
*
*/
orderServiceImpl.addOrder();
System.out.println("我是使用反射机制运行的方法");
}
}
package com.learn;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.learn.service.UserService;
public class Test002 {
public static void main(String[] args) {
/**
* SpringIOC使用了反射机制
* 首先它在这里会去读取一个配置文件
* 读取完了之后呢
* 我会去解析bean的节点
* 我会去拿bean的id
* 是不是这样的
* 我就可以把所有对象做一个初始化操作
* 初始化完毕了以后呢
* 别人只要传入userService这样的一个bean id
* 我就让他去我的Spring容器去找我的id
* 拿到这样一个对象
* 是不是这样子
* 那么这里有很多种做法
* 比如我们通过UserService的bean的id
* 让他去Spring的bean的节点去找到这个id
* 找到这样的一个bean id以后
* 获取到这样的一个class地址
* 然后再使用反射机制
* 去做这样的一个初始化
* 那么这边我告诉你们
* 解析xml要使用什么技术
* 是不是DOM4J
* 所以我告诉你们
* 像SpringIOC的xml版本
* 使用DOM4J加反射技术
* 这是我们要说一下的
* 可能关于XML解析有很多方式
* 你们下去看一下
* 我是怎么知道他这里面要用到反射技术呢
* 我怎么知道他这个对象一定是反射创建的呢
* 怎么做
* 大家想一想
* 我怎么证明他这个对象一定是通过反射创建出来的
* 怎么证明
* 有没有谁能够想起来的
* 无参构造函数
* 我在实现类里面一定要写一下无参构造函数
* 运行
* 无参构造函数初始化......反射技术
* 看到没有
* 无参构造函数初始化 反射技术
* 这边我给你们讲一下
*
* 这个时候我们把构造函数改成私有的
* private UserServiceImpl()
* 我们要把它设置成私有的构造函数
* 看一下这个效果
* 运行
* 能不能初始化
* 照样可以
* 我之前其实讲过的
* 反射私有化还是可以运行出来的
* 之前讲过的
* 怎么可以设置权限的
* 这个其实没用啊
* 这个真没用
* 你的构造函数或者方法私有化
* 都能访问到的
* 这个我就不去细说了
* 这个过程聊不了解
* 了解是吧
* 我就花个十分钟去回顾一下
* 就是怎么去解析这个XML
* 然后我再给你去讲怎么去实现
* 我跟你们讲一下
* 我们可以按照我们自己的实现
* 不一定是按照Spring的实现
* 我给你写两套过程
* 一套是什么呢
* 一套是XML方式的
* 就是他最开始是不会去创建对象
* 当你需要的时候
* 我才会去初始化对象
* 我们写注解版本的时候
* 只要他在调用构造函数的时候
* 我就会去初始化这样的一个bean对象的
*
*
*/
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
/**
* 这里打印一段话分隔一下
* 你们看一下他是怎么实现出来的
* 你们有没有发现相当于一个bean的对象
* 你们看一下bean的对象是在什么时候进行初始化的
* 就相当于你去加载new ClassPathXmlApplicationContext("spring.xml")这样的一个构造函数的时候
* 他就会怎么样
* 就会去初始化的
* 而不是我去取的时候去初始化的
*
*
*/
System.out.println("################################################################################");
/**
* 填你的bean id
* 就是userServiceImpl
*/
UserService userService = (UserService) app.getBean("userService");
/**
* 把class的内存地址打印出来
* com.learn.service.impl.UserServiceImpl@d7b1517
* 是不是可以拿到class地址
*
*
*/
System.out.println(userService);
}
}