1. 注解配置Spring
1.1注解代替配置文件:步骤
1.为配置文件配置新的命名空间
2.开启使用注解代替配置文件
3. 在类中使用注解 完成配置(如果是新版本的spring 框架需要加上一个spring-aop-4.2.4.RELEASE.jar)
4. 因为在项目开发中 ,需要明确的分明注解所在的位置, 所以衍生出来了, 一些功能一样,但是用于表表示的注解
5. 对象是单实例, 还是多实例 ? 用@Scope 这个注解 , 里面的参数scopeName 有两个属性, singleton(多例)|prototype(单例) 如下
6.属性注入
直接写在属性的头上(通过反射的fild 赋值) 破坏了对象的封装性( 回顾:)
// 暴力反射 获取所有的 属性 破坏了 对象的封装
@Test
public void test2() throws Exception {
Field[] fields = User.class.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
}
写在set 方法的头上(通过set 方法进行赋值)
如果在注解中, 只有一个值需要赋值, 而且赋值的属性是value 可以省略key=
7.对象注入
1. 第一种方式 : 自动装配(在容器中自动搜索Car 类型的对象, 但是如果容器中, 有两个同样类型的对象, 怎么找? )
首先对bean 加上@component
然后对属性加
@Autowited 这个注解,有个问题: 如果匹配多个类型一直的对象, 将无法选择注入哪个对象
我们用@qualifier 这个注解辅助@Acutowired 然后就能实现, 选定那个对象
这两个注解制定一个对象, 显的有点麻烦所以,
推荐使用: 直接用个@resource制定键值对, 然后直接加载对象
2. 第二种方法: 直接在配置文件中配置
1.2 . init 和destory 方法
用注解@PostConstruct 和@PreDestroy 这样在构造方法执行后就会执行这个方法, (对象被构造之后 执行这个方法 相当于initmethod 方法)
1.3 STS插件
1. 手动安装插件(成功率比较低)
2. 使用老师的eclipse
3. spring 装好插件的eclipse
是否安装成功,右击applicationContext.xml open with 然后有没有带锤子的文件
1.4 spring 整合junit测试
1.导包spring-test-4.2.4.RELEASE.jar 导入测试包
2.测试
@RunWith(SpringJUnit4ClassRunner.class) 自动创建容器
@ContextConfiguration("classpath:applicationContext.xml") 加载配置文件的地址
有了这两个注解我们不用每次使用时候创建容器对象,然后取出对象, 我们只需要一次把容器创建然后 ,用@Resource(name="user") 然后直接赋值给变量,整个类都可以调用 ,方便了开发, 提高了开发效率
2. Spring AOP
2.1 aop 思想介绍
横向重复, 纵向抽取
2.2. spring 动态代理(spring 生成代理对象)
2.21 spring 能够为管理的容器中的对象生成代理对象
之前我们要实现动态代理我们要调用整个方法 proxy .newproxyinstance(xx,xx,xx)生成代理对象 ,现在spring 直接帮我们解决
什么是 springaop ?
比如我们service 层我们写公用的代码, 然后直接 每个service 都要走整个代理的代码
2.3 spring是实现aop 的原理(动态代理, cglib代理)
动态代理 :被代理对象必须要实现接口, 才能产生代理对象, 如果 没有接口, 就不能实现动态代理
cglib代理 : 因为动态代理的缺陷, spring 引用了第三方代理技术, cglib 这种代理是通过, 对目标对象的继承代理 , 就是这个被代理的 对象是 代理对象的父类(如果目标对象呗final 修饰, 那么该类无法被cglib 代理)
复习 :
定义接口
package com.zzq.Service;
public interface UserService {
void save ();
void update ();
void delete ();
void findAll ();
}
定义实现类
package com.zzq.Service.impl;
import com.zzq.Service.UserService;
public class UserServiceImpl implements UserService {
public void save() {
// TODO Auto-generated method stub
System.out.println("保存用户");
}
public void update() {
// TODO Auto-generated method stub
System.out.println("更新用户");
}
public void delete() {
// TODO Auto-generated method stub
System.out.println("删除用户");
}
public void findAll() {
// TODO Auto-generated method stub
System.out.println("查找用户");
}
}
动态代理工厂
package com.zzq.proxy;
import java.lang.reflect.InvocationHandler;
public class UserServiceProxyFactory implements InvocationHandler {
public UserServiceProxyFactory(UserService us) {
super();
this.us = us;
}
private UserService us;
public UserService getUserServiceProxy(){
//生成动态代理
UserService usProxy = (UserService) Proxy.newProxyInstance(
UserServiceProxyFactory.class.getClassLoader(),
UserServiceImpl.class.getInterfaces(),
this
);
//返回
return usProxy;
}
public Object invoke(Object arg0, Method method, Object[] arg2) throws Throwable {
System.out.println("打开事务!");
Object invoke = method.invoke(us, arg2);
System.out.println("提交事务!");
return invoke;
}
}
Cglib代理 工厂的创建
package com.zzq.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.zzq.Service.UserService;
import com.zzq.Service.impl.UserServiceImpl;
/**
* cglib代理
* @author ZZQ.Hacker
*
*/
public class UserServiceProxyFactory2 implements MethodInterceptor {
public UserService getUserServiceProxy(){
Enhancer en = new Enhancer();//帮我们生成代理对象
en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
en.setCallback(this);//代理要做什么
UserService us = (UserService) en.create();//创建代理对象
return us;
}
public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
//打开事务
System.out.println("打开事务!");
//调用原有方法
Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
//提交事务
System.out.println("提交事务!");
return returnValue;
}
}
测试类 , 调用代理对象
package com.zzq.proxy;
import org.junit.Test;
import com.zzq.Service.UserService;
import com.zzq.Service.impl.UserServiceImpl;
public class Demo {
@Test
public void test(){
UserService userService = new UserServiceImpl() ;
UserServiceProxyFactory factory = new UserServiceProxyFactory(userService);
UserService uproxy = factory.getUserServiceProxy();
uproxy.save();
}
@Test
public void test2(){
UserServiceProxyFactory2 factory = new UserServiceProxyFactory2() ;
UserService usp = factory.getUserServiceProxy();
usp.findAll();
System.out.println(usp instanceof UserServiceImpl); // 判断代理对象是否属于代理对象的类型, 由于是继承关系 所以一定是true 90
}
}
通过
System.out.println(usp instanceof UserServiceImpl);
我们可以看出 caglib代理 是通过继承的代理
动态代理 是代理对象 与被代理对象直接没有关系, 同时实现了同一个接口, 没有继承关系
2.4 aop 名词学习
joinpoint(连接点) : 目标中, 所有可以增强的方法( 这里举个例子 : 比如老师手里有一把刀,那么,学生就是链接点,因为老师有可能捅死每个学生, 有一天真的愤怒了直接捅死一个, 这个一个或者多个, 就是切入点)
Pointcut(切入点): 目标对象, 已经 增强的方法
Advice (通知/增强): 增强的代码
Target (目标对象) : 被代理的对象
weaving(织入): 将通知织入切点 (把同之应用到链接点 形成切入点)
proxy (代理) : 将通知,植入目标代理对象, 之后这个过程叫代理
aspect (切面) : 切入点+通知
3.spring aop 演示
3.1步骤 :
1.导包
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar 织入包(第三方包)
com.springsource.org.aopalliance-1.0.0.jar aop 联盟包(第三方包)
spring-aspects-4.2.4.RELEASE.jar spring aop 包
2. 准备目标对象
3.准备通知(MyAdvice)
package com.zzq.springaop;
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("这是后置通知(出现异常也会调用)!!");
}
}
4.通知进行织入目标对象
1.导入aop 约束
2.配置配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
<!-- 准备工作: 导入aop(约束)命名空间 -->
<!-- 1.配置目标对象 -->
<bean name="userService" class="com.zzq.Service.impl.UserServiceImpl" ></bean>
<!-- 2.配置通知对象 -->
<bean name="myAdvice" class="com.zzq.springaop.MyAdvice" ></bean>
<!-- 3.配置将通知织入目标对象 -->
<aop:config>
<!-- 配置切入点
public void cn.itcast.service.UserServiceImpl.save()
void cn.itcast.service.UserServiceImpl.save()
* cn.itcast.service.UserServiceImpl.save()
* cn.itcast.service.UserServiceImpl.*()
* cn.itcast.service.*ServiceImpl.*(..)
* cn.itcast.service..*ServiceImpl.*(..)
-->
<aop:pointcut expression="execution( * com.zzq.Service.impl..*ServiceImpl.*(..))" id="pc"/>
<aop:aspect ref="myAdvice" >
<!-- 指定名为before方法作为前置通知 -->
<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>
3. 进行测试
package com.zzq.springaop;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.zzq.Service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/zzq/springaop/applicationContext.xml")
public class Demo {
@Resource(name="userService")
private UserService us;
@Test
public void fun1(){
us.delete();;
}
}
4.aop 整理1. 面向切面编程思想(跨语言跨平台, 跨物种)横向重复代码, 纵向抽取代码
2.动态代理, 可以体现aop思想 ,把对象中的方法进行增强(接口)
3.spring aop 开发 spring 封装了动态代理代码,我们就不用手写动态代理方法了, 还封装了 第三方代理, cglib (继承)代理,可以对任何类进行代理
4.spring 中的名词
Pointcut(切入点): 目标对象, 已经 增强的方法
Advice (通知/增强): 增强的代码
Target (目标对象) : 被代理的对象
weaving(织入): 将通知织入切点 (把同之应用到链接点 形成切入点)
proxy (代理) : 将通知,植入目标代理对象, 之后这个过程叫代理
aspect (切面) : 切入点+通知
5.spring 注解配置(了解)