文章目录
1. 动态获取spring配置文件 1.修改SunWebApplicationContext.java 2.修改SunDispatcherServlet.java
2.自定义Service注解 1.需求分析 2.编写Monster.java 3.自定义Service注解 4.编写Service接口MonsterService.java 5.编写Service实现类MonsterServiceImpl.java 6.修改SunWebApplicationContext.java的executeInstance方法,增加对Service注解的扫描 7.debug测试
3.完成自定义Autowired注解 1.自定义Autowired注解 2.在SunWebApplicationContext.java中添加方法executeAutoWired完成属性的自动装配 3.修改MonsterController.java来使用Autowired注解 4.单元测试
4.当前阶段完成的任务 自定义两个注解 目前对SpringMVC容器的简单理解
1. 动态获取spring配置文件
1.修改SunWebApplicationContext.java
2.修改SunDispatcherServlet.java
2.自定义Service注解
1.需求分析
2.编写Monster.java
package com. Sun . entity;
public class Monster {
private Integer id;
private String name;
private String skill;
private Integer age;
public Monster ( Integer id, String name, String skill, Integer age) {
this . id = id;
this . name = name;
this . skill = skill;
this . age = age;
}
public Integer getId ( ) {
return id;
}
public void setId ( Integer id) {
this . id = id;
}
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public String getSkill ( ) {
return skill;
}
public void setSkill ( String skill) {
this . skill = skill;
}
public Integer getAge ( ) {
return age;
}
public void setAge ( Integer age) {
this . age = age;
}
@Override
public String toString ( ) {
return "Monster{" +
"id=" + id +
", name='" + name + '\'' +
", skill='" + skill + '\'' +
", age=" + age +
'}' ;
}
}
3.自定义Service注解
package com. Sun . sunspringmvc. annotation;
import java. lang. annotation. * ;
@Target ( ElementType . TYPE )
@Retention ( RetentionPolicy . RUNTIME )
@Documented
public @interface Service {
String value ( ) default "" ;
}
4.编写Service接口MonsterService.java
package com. Sun . sunspringmvc. annotation;
import java. lang. annotation. * ;
@Target ( ElementType . TYPE )
@Retention ( RetentionPolicy . RUNTIME )
@Documented
public @interface Service {
}
5.编写Service实现类MonsterServiceImpl.java
package com. Sun . service. Impl;
import com. Sun . entity. Monster;
import com. Sun . service. MonsterService;
import com. Sun . sunspringmvc. annotation. Service;
import java. util. ArrayList ;
import java. util. List ;
@Service
public class MonsterServiceImpl implements MonsterService {
public List < Monster > listMonsters ( ) {
ArrayList < Monster > monsters = new ArrayList < Monster > ( ) ;
monsters. add ( new Monster ( 1 , "牛魔王" , "芭蕉扇" , 500 ) ) ;
monsters. add ( new Monster ( 2 , "蜘蛛精" , "吐口水" , 200 ) ) ;
return monsters;
}
}
6.修改SunWebApplicationContext.java的executeInstance方法,增加对Service注解的扫描
public void executeInstance ( ) {
for ( String classPath : classFullPathList) {
try {
Class < ? > aClass = Class . forName ( classPath) ;
if ( aClass. isAnnotationPresent ( Controller . class ) ) {
String name = aClass. getSimpleName ( ) . substring ( 0 , 1 ) . toLowerCase ( ) + aClass. getSimpleName ( ) . substring ( 1 ) ;
singleObjects. put ( name, aClass. newInstance ( ) ) ;
} else if ( aClass. isAnnotationPresent ( Service . class ) ) {
Service annotation = aClass. getAnnotation ( Service . class ) ;
String value = annotation. value ( ) ;
Object bean = aClass. newInstance ( ) ;
if ( "" . equals ( value) ) {
String simpleName = aClass. getSimpleName ( ) ;
String beanName = simpleName. substring ( 0 , 1 ) . toLowerCase ( ) + simpleName. substring ( 1 ) ;
singleObjects. put ( beanName, bean) ;
Class < ? > [ ] interfaces = aClass. getInterfaces ( ) ;
for ( Class < ? > anInterface : interfaces) {
String interfaceSimpleName = anInterface. getSimpleName ( ) ;
String beanName2 = interfaceSimpleName. substring ( 0 , 1 ) . toLowerCase ( ) + interfaceSimpleName. substring ( 1 ) ;
singleObjects. put ( beanName2, bean) ;
}
} else {
singleObjects. put ( value, bean) ;
}
}
} catch ( ClassNotFoundException e) {
throw new RuntimeException ( e) ;
} catch ( InstantiationException e) {
throw new RuntimeException ( e) ;
} catch ( IllegalAccessException e) {
throw new RuntimeException ( e) ;
}
}
}
7.debug测试
3.完成自定义Autowired注解
1.自定义Autowired注解
package com. Sun . sunspringmvc. annotation;
import java. lang. annotation. * ;
@Target ( ElementType . FIELD )
@Retention ( RetentionPolicy . RUNTIME )
@Documented
public @interface AutoWired {
String value ( ) default "" ;
}
2.在SunWebApplicationContext.java中添加方法executeAutoWired完成属性的自动装配
public void executeAutoWired ( ) throws IllegalAccessException {
if ( singleObjects. isEmpty ( ) ) {
return ;
}
for ( Object beanObject : singleObjects. values ( ) ) {
Class < ? > aClass = beanObject. getClass ( ) ;
Field [ ] declaredFields = aClass. getDeclaredFields ( ) ;
for ( Field declaredField : declaredFields) {
if ( declaredField. isAnnotationPresent ( AutoWired . class ) ) {
AutoWired annotation = declaredField. getAnnotation ( AutoWired . class ) ;
String value = annotation. value ( ) ;
Object findBeanObject = null ;
if ( "" . equals ( value) ) {
String simpleName = declaredField. getType ( ) . getSimpleName ( ) ;
String beanName = simpleName. substring ( 0 , 1 ) . toLowerCase ( ) + simpleName. substring ( 1 ) ;
findBeanObject = singleObjects. get ( beanName) ;
} else {
findBeanObject = singleObjects. get ( value) ;
}
if ( findBeanObject == null ) {
throw new RuntimeException ( "容器中不存在你要装配的bean" ) ;
} else {
declaredField. setAccessible ( true ) ;
declaredField. set ( beanObject, findBeanObject) ;
}
}
}
}
}
3.修改MonsterController.java来使用Autowired注解
4.单元测试
4.当前阶段完成的任务
自定义两个注解
自定义Service注解:在原有的扫描所有文件全类名的基础上增加逻辑,判断是否具有Service注解,并根据value值或者默认方案将其注入到bean中 自定义Autowired注解
遍历所有单例池对象,获取对应的Class对象 获取每个对象的所有字段 对每个字段判断是否有Autowired注解,如果有则按照类型首字母小写或者value值来进行依赖注入
目前对SpringMVC容器的简单理解
tomcat启动,加载中央控制器 获取spring配置文件路径,使用这个路径创建一个spring容器 调用spring容器的init方法,初始化spring容器
读取配置文件,得到要扫描的包,从而得到包的工作路径 根据工作路径来得到包内所哟class文件的全路径 遍历所有class文件的全路径,得到Class对象 使用反射扫描指定注解,反射创建bean对象,放到单例池中 Autowired依赖注入
扫描单例池,得到所有对象,从而得到Class对象 使用反射得到所有字段信息,判断是否有Autowied注解,如果有则根据一定规则从单例池中查找bean对象进行依赖注入 初始化映射对象列表
扫描单例池,得到Class对象 通过反射判断是否有RequestMapping注解,如果有则使用反射获取url和Method对象,再加上当前的对象,封装到映射对象中 将这个映射对象添加到映射对象列表 请求分发
浏览器向中央控制器发送请求 中央控制器根据请求的uri和映射对象列表的url进行比对 如果匹配则反射调用Controller的方法