package Test;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.junit.Test;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import pojo.BNBA;
import pojo.aCatRefDI;
import pojo.aUser;
import pojo.cDog;
import pojo.cPerson;
import pojo.cUser;
//进行单元测试类
public class TestSping {
//---------------------------1.对引用类型参数进行简化 自动装配autowire,使用acat,auser,adog,test01-------------------------------------
/*
自动装配方式一: autowire="byName"取代了<property>标签
<bean>
<bean autowire="byName"></bean>取代了 <property></property>
</bean>
以前 <bean>
<property ref="引用类型"></property>
</bean>
现在配置文件中
<bean id="user" class="pojo.aUser" autowire="byName"></bean>
主要作用: 自动装配autowire="byName"取代了<property>标签
配置文件内容:
<bean id="user" class="pojo.aUser" autowire="byType"></bean>
<bean id="cat" class="pojo.aCatRefDI"></bean>
<bean id="dog" class="pojo.aDogRefDI"></bean>
知识点1.1
***byName的原理,实体类中必须有set方法才行
第一步:对bean标签进行解析,遇到autowire="byName"的属性时,spring会自动找到类中的成员变量的set方法。
第二步:setDog解析时,会先把set去掉,然后得到 Dog单词,再进行首字母的小写,得到 dog。那么,该dog就是bean标签中的id属性的值
第三步:spring根据dog,找到配置文件中的<bean id="dog">之后,进行依赖注入
if(匹配成功){dog对象注入到user对象中}
else(匹配不成功){null注入到user对象中}
自动装配方式二: autowire="byType"取代了<property>标签
知识点1.2
***byType的原理,实体类中必须有set方法才行
第一步:对bean标签进行解析,遇到autowire="byType"的属性时,spring会自动找到类中的成员变量的set方法。
第二步:setDog解析时,会先找到setDog(Dog dog)方法中的形参类型Dog,然后找到Dog类所在的包,拼接一个包名 pojo.Dog
第三步:spring根据pojo.Dog,找到配置文件中的<bean class="pojo.Dog">之后,进行依赖注入
if(匹配成功){dog对象注入到user对象中}
else(匹配不成功){null注入到user对象中}
配置文件内容:
<bean id="user" class="pojo.aUser" autowire="byName"></bean>
<bean id="cat" class="pojo.aCatRefDI"></bean>
<bean id="dog" class="pojo.aDogRefDI"></bean>
自动装配方式三:
知识点1.3
全局自动装配<beans>头标签中default-autowire="byType|byName"
配置文件内容:
头标签中:<beans default-autowire="byType"></beans>
<bean id="user" class="pojo.aUser"></bean>
<bean id="cat" class="pojo.aCatRefDI"></bean>
<bean id="dog" class="pojo.aDogRefDI"></bean>
//----------------------2.对引用类型参数进行简化 属性的注解形式 propertyAnnotation @Autowired-使用acat,auser,adog,test01---------------------------
知识点1.4使用属性注解形式 propertyAnnotation,取代了<bean autowire="byName|byType">,实体类中的set方法全部省去
a.属性注解的形式是 : @Autowired
b.属性注解在类的成员变量上面添加@Autowired,取代了<bean autowire="byName|byType">,又可以把实体类中的set方法全部省去
前提条件在配置文件中写上<beans>头文件约束和开启属性注解扫描
c.使用步骤:
c.1在类的成员变量上,添加@Autowired -> User类中属性 @Autowired
c.2编写配置文件,添加了头文件约束
添加一句xsi:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=""中添加
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
c.3在配置文件中,添加了开启属性注解的扫描
<context:annotation-config/>
配置文件中内容
<context:annotation-config/>
<bean id="user" class="pojo.aUser" ></bean>
<bean id="cat" class="pojo.aCatRefDI"></bean>
<bean id="dog" class="pojo.aDogRefDI"></bean> byName
<bean id="dogA" class="pojo.aDogRefDI"></bean> byType
***原理:@Autowired 相当于autowire="byName" autowire="byType"
第一步:spring容器加载时,会进行解析核心配置文件,当解析到<context:annotation-config/> 标签时,扫描每个<bean>标签对应的类中的属性注解
第二步:当解析类中的属性注解时,遇到成员变量添加了@Autowired,会进行自动装配的过程
第三步:先进行自动装配byName的过程,根据成员变量的名称,得到id,举例:private aDogRefDI dog中的dog,拿到dog去匹配bean标签id,
如果匹配成功,那么自动的进行依赖注入,不需要set方法的支持。如果匹配不成功,那么采用自动装配byType的过程
byType的过程,根据成员变量的类型,得到 class类型,举例:private aCatRefDI cat中的aCatRefDI去匹配bean标签class,
如果匹配成功,那么自动的进行依赖注入,如果不成功,注入null值。
*/
@Test
public void test01(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取User对象
aUser user=(aUser) context.getBean("user");
System.out.println(user);
}
//---------------------------3.类注解 @Component -使用acat,auser,adog,test02-------------------------------------------------------------
/*
* 类的注解-简化配置文件中的<bean>标签,取代了整个<bean标签>,1.需要把spring用到的类都添加上@Component2.类中必须添加属性的注解@Autowired,不能省3.配置文件中开启包扫描
a.类的注解的形式 @Component,在类的上面添加 @Component
b.类注解@Component取代了整个<bean标签>,前提条件1.需要把spring用到的类都添加上@Component
2.类中必须添加属性的注解@Autowired,不能省
3.配置文件中开启包扫描
***注意c:类的注解实现步骤:
第一步:在配置文件中开启包扫描
<context:component-scan base-package="XXX,例如pojo"></context:component-scan>
第二步:在base-package="XXX,例如pojo"中pojo想要被spring管理的类添加
@Component
配置文件中
<context:component-scan base-package="pojo"></context:component-scan>
注意:开启包扫描的同时,开启了属性的注解。
配置文件内容:
<context:component-scan base-package="pojo"/>
***注意d:类注解执行原理
第一步:spring加载配置文件,读取到<context:component-scan base-package="包的路径">标签
第二步:spring首先会根据包扫描,对包中的所有的javabean都进行扫描。遇到@Component的注解,会先进行的对象的加载,相当于<bean>标签创建对象
第三步:spring然后会继续扫描属性注解,遇到属性注解@Autowired,会进行自动装配的过程,完成对javabean对象的依赖注入
*/
@Test
public void test02(){
//spring容器启动时,就完成了回调函数setName()
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//获取User对象
aUser user=(aUser) context.getBean("aUser");
System.out.println(user);
}
//--------------------------4.类的id生成策略--使用BNBA,test03----------------------------------
@Test
public void test03(){
//spring容器启动时,就完成了回调函数SetName()
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//使用@Component(value="ABC") 强制指定了id属性的值,类的id
/*
因为类注解@Component省略了<bean>标签,所以查看类id生成的策略
类名 类的id <bean id="">
NBA NBA
nBA nBA
NbA nbA
nbA nbA
id的生成规则,根据类名中的第二个字母判断,如果第二个字母是小写的,类的id的首字母变为小写,其余不变。
测试方法:
使用了spring提供的接口implements BeanNameAware
添加了接口中未实现的方法: setBeanName(String name)
在spring容器加载配置文件时,执行了回调函数setBeanName()方法,进行了id的输出测试
*/
}
//--------------------5.spring容器进行简单类型+复杂类型+引用类型的赋值操作-使用cdog,cperson,cuser,test04---------------------------
/*
简单类型
@Value(value="张三丰") //简单类型进行赋值,取代了<property>
private String name;
如果想要使用配置文件进行简单类型的赋值,
1.创建new file->config.properties->输入内容name=\u6C88\u5FD7\u6052 age=20
2.配置文件中 引入外部配置文件
<context:property-placeholder location="classpath:/config.properties"/>
3.实体类中简单类型使用 @Value("${配置文件中的变量名}")
引用类型
@Autowired //引用类型赋值,属性注解@Autowired取代了<bean autowire="byName|byType">, 而autowire取代了<property>标签
private cDog dog;
复杂类型
配置文件中,
头文件中添加头文件约束util
添加xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation中添加http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd"
举例list
<util:list id="list">
<value>5</value>
<value>999</value>
</util:list>
实体类赋值类中@Value("#{@list}") @Value("#{@id的值}")
取代了<property>标签
*/
@Test
public void test04(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
cUser user=(cUser) context.getBean("cUser");
List list = new ArrayList();
list.add("一");
list.add("二");
user.setList(list);
System.out.println(user);
cPerson person = (cPerson) context.getBean("cPerson");
System.out.println(person);
//cPerson与cUser类一模一样,在cUser添加set方法进行list的设置,发现在user对象生成之后,改变其中list的值,下次一模一样的person对象中的list值,并不会改变
//说明以后需要配置的静态资源或者是公共的资源,使用工具标签进行配置util
}
}
package web;
import javax.servlet.annotation.ServletSecurity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import pojo.User;
import service.UserService;
//注意:在接口类中不用加类注解
//模拟controller层 控制层
@Controller //专门用于表示控制层servlet的注解
public class UserServlet {
//Servlet依赖Service,所以需要使用service对象,接口即可
@Autowired
private UserService userService;
//上面这一步相当于完成了bean标签的设计<bean id="xxxxxx" class="service.UserServiceImpl">
//因为接口无法直接进行依赖注入,根据接口去找到了接口的实现类。
/*
1.接口的实现类 UserServiceImpl使用了@Sevice 生成了id="UserServiceImpl" class="service.UserServiceImpl"
2.接口依赖时,private UserService userService;
因为接口无法直接进行依赖注入,相当于spring先找到了接口的实现类,然后根据class属性也就是byType的自动装配过程
id=xxxxxxxxxxxxx class="service.UserServiceImpl"
id=UserServiceImpl class="service.UserServiceImpl" id失败,根据class,class底层都是UserService
3.如果装配成功了
UserService userService=new UserServiceImpl();
*/
//为什么不是UserServiceImpl而是UserService
/*
面向接口编程
经常见到的形式 : List list = new ArrayList();
面向接口编程:是一种设计模式。
作用:能使业务逻辑的方法,与业务逻辑的具体实现进行分离。
举例:UserService接口,有addUser(User user)方法,
UserServiceImpl,实现了接口,并进行了方法的重写
好处:1.从设计层角度,一般 架构师或者开发经理,会实现把需要的接口定义好,而程序员只需要实现具体的业务逻辑即可。
2.从开发角度,依赖的接口不变,而实现类发生了改变,包括类名也变化了,但是,对这个程序流程来说,没有任何影响,
举例:UserServlet中依赖的为UserService接口,
而UserServiceImpl实现类,变为了UserServicesdg都无影响
原理:第一步:spring加载配置文件时,读取类的注解
第二步,UserServiceImpl 添加了类的注解,相当于 <bean id="userServiceImpl" class="service.UserServcieImpl"> </bean>
第三步,spring读取到了UserServlet注解,然后@Autowired表示需要依赖注入userService
第四步,spring发现UserService为一个接口,无法直接进行依赖注入,根据接口,找到了接口的实现类
根据id="userServcie"是无法找到的,根据class类型去找到,匹配成功之后,完成依赖注入的自动装配
建议:在项目过程中,实现接口的类,最好为一个,
*/
/*
*
1.综合案例:使用MVC分层思想,完成用户模块的新增用户功能
具体的实现步骤:
a.先导包,然后 创建 package : pojo,dao,service,web,test
b.编写配置文件,使用 头文件约束 :context 属性注解@Autowired使用
c.配置文件中,开启包扫描
d.编写对应的实体类,这些实体类分布在不同的包下。对每一个类添加相应的注解,完成依赖注入的自动装配过程
e.编写单元测试
2.spring注解的高级用法
@Repository //表示dao层
@Service //表示service层
@Controller //表示controller层
@Component //表示任意一个类的注解
@Lazy(true) //懒加载生效
@Scope("prototype") //多例模式
*/
public void addUser(User user){ //添加用户
userService.addUser(user);
}
}