Spring负责管理项目中的所有对象,Spring看作是项目中对象的管家
Spring框架的功能:aop支持、ioc思想、spring jdbc、aop事务、junit测试支持
Spring搭建:
导包:beans、context、core、exception四个基础包
apache日志包
创建实体类对象
书写配置文件:建议文件名为applicationContext.xml
导入约束文件Schema约束
代码测试:1、创建容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext(“applicationContext.xml”);
2、从容器中获得实体对象
User user=(User)ac.getBean(“User”);
3、打印该对象
System.out.println(user);
Spring思想:
ioc:反转控制
反转控制就是创建对象的方式反转了。以前对象的创建由开发人员自己维护,包括依赖关系也是自己注入;使用spring之后,对象的创建以及以来关系可以由spring完成创建以及注入。
反转控制就是反转了对象的创建方式。从我们自己创建反转给了程序
di:依赖注入(注入就是赋值)
实现ioc思想需要di做支持
注入的方式:set方法注入、构造方法注入、字段注入
注入的类型:值类型注入---8大基本数据类型
引用类型注入---将依赖对象注入
ApplicationContext&BeanFactory
BeanFactory接口:spring原始接口,针对原始接口的实现类功能较为单一
BeanFactory接口实现类的容器,特点是每次在获得对象时才会创建对象
ApplicationContext:每次容器启动时就创建容器中配置的所有对象,并提供更多的功能
从类路径下加载配置文件:ClassPathXmlApplicatiionContext
从硬盘绝对路径下加载配置文件:FileSystemXmlApplicationContext(d:/aaa/ddd/fff)
总结:在web开发中,使用applicationContext,在资源匮乏时使用BeanFactory。
Spring配置文件详解:
Bean元素:
将User对象交给spring容器管理
Bean元素:使用该元素描述需要spring容器管理的对象
Class属性:被管理对象的完整类名
name属性:给被管理的对象起个名字。获得对象时根据该名称获得对象,可以重复,可以使用特殊字符(尽量使用name属性)
id属性:与name属性一模一样,但是名称不可重复,不能使用特殊字符
Spring创建对象的方式:
空参构造方式:<bean name=”user” class=”com.domain.User”></bean>
Bean元素进阶:
Scope属性
Singleton(默认值):单例对象,被标识为单例的对象在spring容器中只会存在一个实例
Prototype:多例原型,被标识为多例的对象,每次再获得再会创建,每次创建都是新的对象。
Spring的分模块配置
<!--导入其他spring配置文件-->
<import resource=”com.domain/applicationContext.xml”/>
Spring属性注入:
Set方法注入
构造函数注入
复杂类型注入(数组、list、map、properties)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd "> <!-- 将User对象交给Spring容器来管理 --> <!-- 通过set方法进行注入 --> <bean name="user" class="com.domain.User"> <!-- 值注入,也就是变量赋值 --> <property name="name" value="张三"></property> <property name="age" value="18"></property> <!-- 引用类型注入 --> <property name="car" ref="car"></property> </bean> <bean name="car" class="com.domain.Car"> <!-- 值注入 --> <property name="cname" value="兰博基尼"></property> <property name="color" value="黄色"></property> </bean> <!-- 通过构造方法进行注入 --> <bean name="user1" class="com.domain.User"> <constructor-arg name="name" value="8" index="0" type="java.lang.Integer"></constructor-arg> <constructor-arg name="car" ref="car" index="1"></constructor-arg> </bean> </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd "> <!-- 通过set方法进行注入 --> <bean name="user" class="com.domain.User"> <!-- 值注入,也就是变量赋值 --> <property name="name" value="张三"></property> <property name="age" value="18"></property> <!-- 引用类型注入 --> <property name="car" ref="car"></property> </bean> <bean name="car" class="com.domain.Car"> <!-- 值注入 --> <property name="cname" value="兰博基尼"></property> <property name="color" value="黄色"></property> </bean> <bean name="cd" class="com.collection.CollectionDemo"> <!-- 数组 --> <property name="arr"> <array> <!-- 值注入 --> <value>张三</value> <value>李四</value> <!-- 引用注入 --> <ref bean="user" /> </array> </property> <!-- List集合 --> <property name="list"> <list> <value>孙悟空</value> <value>猪八戒</value> <ref bean="car" /> </list> </property> <!-- Map类型注入 --> <property name="map"> <map> <entry key="123" value="asd"></entry> <entry key="user" value-ref="car"></entry> <entry key-ref="user" value-ref="car"></entry> </map> </property> <!-- properties类型注入 --> <property name="prop"> <props> <prop key="driver">123</prop> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>
package com.collection; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.domain.User; public class Demo { @Test public void method1() { // 1.得到容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml"); // 2.管容器要一个对象 CollectionDemo cd = (CollectionDemo) ac.getBean("cd"); Object[] obj = cd.getArr(); for (Object o : obj) { System.out.println(o); } } @Test public void method2() { // 1.得到容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml"); // 2.管容器要一个对象 CollectionDemo cd = (CollectionDemo) ac.getBean("cd"); // 管对象要一个list List list = cd.getList(); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } } @Test public void method3() { // 1.得到容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml"); // 2.管容器要一个对象 CollectionDemo cd = (CollectionDemo) ac.getBean("cd"); // 管对象要一个map Map map = cd.getMap(); Set set = map.entrySet(); Iterator<Map.Entry> it = set.iterator(); while (it.hasNext()) { Map.Entry m = it.next(); System.out.println(m.getKey() + "---" + m.getValue()); } } @Test public void method4() { // 1.得到容器对象 ApplicationContext ac = new ClassPathXmlApplicationContext("com/collection/applicationContext.xml"); // 2.管容器要一个对象 CollectionDemo cd = (CollectionDemo) ac.getBean("cd"); // 管对象要一个properties Properties prop = cd.getProp(); Set<String> set = prop.stringPropertyNames(); for (String str : set) { System.out.println(str + "--" + prop.getProperty(str)); } } }
使用注解配置spring
1、为主配置文件引入新的命名空间(约束)
2、开启使用注解代理配置文件
3、在类中使用注解完成配置
将对象注入到容器
@Component(“user”)
@Service(“user”) //service层
@Controller(“user”) //web层
@Repository(“user”) //dao层
修改对象的作用范围
@Scope(scopeName=”prototype”)
值类型注入:@Value(“tom”)
Private String name;//通过反射的Field赋值,破坏了封装性
@Value(“tom”)
Public void setName(String name){
This.name=name;
}//通过set方法赋值,推荐使用
引用类型注入:@Autowired//自动装配
@Qualifier(“car”)//使用@Qualifier注解告诉spring容器自动装配哪个名称的对象
Private Car car; //两个配置使用
初始化|销毁方法
@PostConstruct //在对象被创建后调用,init-method
@PreDestory //在销毁之前调用,destory-method
Spring与Junit整合测试:
导包:基础包4个和日志包两个+aop+test
配置注解:@RunWith(SpringJunit4ClassRunner.class)//帮我们创建容器
@ContextConfiguration(“classpath:applicationContext.xml”)//指定创建容器时使用哪个配置文件
测试
package com.service; //目标对象(UserService被代理的对象) public class UserService { public void add() { System.out.println("这是新增的方法"); } public void delete() { System.out.println("这是删除的方法"); } public void update() { System.out.println("这是更新的方法"); } public void find() { System.out.println("这是查找的方法"); } }
package com.service; //spring与Junit的整合,适用于测试 import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.domain.User; //创建容器 @RunWith(SpringJUnit4ClassRunner.class) // 指定创建容器时使用哪个配置文件 @ContextConfiguration("classpath:applicationContext.xml") public class Demo01 { @Autowired @Qualifier("userService") private UserService userService; @Test public void method() { userService.add(); } }
aop思想
Spring能够为容器中管理的对象生成动态代理对象
动态代理(优先):被代理的对象必须实现接口,才能产生代理对象,如果没有,将不能产生动态代理技术
Cglib代理(没有接口):第三方代理技术,cglib代理。可以对任何类生成代理。代理的原理是对目标对象进行继承代理。如果目标对象被final修饰,那么该类无法被cglib代理。
名词学习:
Joinpoint(连接点):目标对象中,所有可以增强的方法
Pointcut(切入点):目标对象,已经增强的方法
Advice(通知/增强):增强的代码
Target(目标对象):被代理对象
Weaving(织入):将通知应用到切入点的过程
Proxy(代理):将通知织入到目标对象之后,形成代理对象
Aspect(切面):切入点+通知
package com.service; import org.aspectj.lang.ProceedingJoinPoint; //通知 public class MyAdvice { // 前置通知 public void before() { System.out.println("这是前置通知"); } // 后置通知 public void afterReturning() { System.out.println("这是后置通知,在异常的时候不调用"); } // 环绕通知 public Object around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("这是环绕通知之前的部分"); Object proceed = pjp.proceed(); System.out.println("这是环绕通知之后的部分"); return proceed; } // 异常通知 public void afterException() { System.out.println("这是异常通知,在出现异常的时候调用"); } // 后置通知 public void after() { System.out.println("后置通知,在出现异常的时候调用"); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd "> <!-- 配置目标对象 --> <bean name="userService" class="com.service.UserService"></bean> <!-- 配置通知 --> <bean name="myAdvice" class="com.service.MyAdvice"></bean> <!-- 配置切入点 --> <aop:config> <aop:pointcut expression="execution(* com.service.*Service.*(..))" id="pc"/> <aop:aspect ref="myAdvice"> <aop:before method="before" pointcut-ref="pc"/> <aop:after-returning method="afterReturning" pointcut-ref="pc"/> <aop:around method="around" pointcut-ref="pc"/> <aop:after-throwing method="afterException" pointcut-ref="pc"/> <aop:after method="after" pointcut-ref="pc"/> </aop:aspect> </aop:config> </beans>