Spring注解
步骤
导包4+2+spring-aop
为主配置文件引入新的命名空间(约束)
开启使用注解代替配置文件
<!--开启注解
指定扫描 base-package下的所有注解
-->
<context:component-scan base-package="cn.probuing.bean"></context:component-scan>
在类中使用注解完成配置
将对象注册到容器
@Component("user")
@Service("user")//service层
@Controller("user")//web层
@Repository("user")//dao层
指定对象的作用范围
//指定对象的作用范围
@Scope(scopeName = "prototype")
值类型注入
@Value("tom")
private String name;
通过反射的Field赋值,破坏了封装性
@Value("JACK")
public void setName(String name) {
this.name = name;
}
通过set方法赋值,推荐使用
引用类型注入
引用类型注入,需要先将引用类型注册到容器中
@Component("car")
public class Car {
private String name;
private String color;
public String getName() {
return name;
}
@Value("BMW")
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
@Value("green")
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}
- 注入方式一:自动装配 自动扫描引用类型
@Autowired
private Car car;
这种方式不好的地方在于 如果匹配到多个类型一致的对象将无法选择具体注入的对象可以通过辅助注解解决,指定自动装配的装配对象
@Qualifier("car2")
- 注入方式二:手动注入,指定注入哪个名称的对象
@Resource(name = "car")
private Car car;
初始化|销毁方法
/**
* 在对象创建后调用 相当于init-method
*/
@PostConstruct
public void init() {
System.out.println("user初始化");
}
/**
* 在销毁方法之前调用
*/
@PreDestroy
public void destroy() {
System.out.println("user销毁");
}
Spring与Junit整合测试
1.导包4+2+aop+test
配置详解
创建配置获得容器对象,测试代码
//帮我们创建容器,并调用指定class的方法
@RunWith(SpringJUnit4ClassRunner.class)
//指定创建容器时使用哪个配置文件
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringJunitDemo {
//获得Spring管理的对象
@Resource(name = "user")
private User u;
@Test
public void fun1() {
System.out.println(u);
}
}
AOP思想
图片.pngSpring中的AOP
Spring中的AOPSpring实现aop的原理
动态代理
被代理对象必须要实现接口,才能产生代理对象,如果没有接口将不能使用动态代理技术
cglib代理
第三方代理技术,cglib代理.可以对任何类生成代理.代理的原理是对目标对象进行继承代理. 如果目标对象被final修饰.那么该类无法被cglib代理.
aop名词
名词解释Spring使用aop
Spring使用aop开发就是指的是:Spring封装了动态代理的代码,还封装了cglib,我们不需要手写动态代理代码
xml配置方式
导包
spring-aspects-4.2.4.RELEASE.jar
spring-aop-4.2.4.RELEASE.jar
- 第三方包
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
准备目标对象
准备通知
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 afer() {
System.out.println("后置通知,出现异常也会调用");
}
}
配置进行织入,将通知织入目标对象中
<!--配置目标对象-->
<bean name="userServiceTarget" class="cn.probuing.proxy.UserServiceImpl"/>
<!--配置通知对象-->
<bean name="myAdvice" class="cn.probuing.advice.MyAdvice"/>
<!--配置将通知置入目标对象-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="pc" expression="execution(* cn.probuing.proxy..*ServiceImpl.*(..))"/>
<!--描述通知-->
<aop:aspect ref="myAdvice">
<!--前置通知-->
<aop:before method="before" pointcut-ref="pc"/>
<!--后置通知-->
<aop:after method="afer" pointcut-ref="pc"/>
<!--后置通知 异常不关闭-->
<aop:after-returning method="afterReturning" pointcut-ref="pc"/>
<!--异常拦截通知-->
<aop:after-throwing method="afterException" pointcut-ref="pc"/>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:cn/probuing/aop/applicationContext.xml")
public class AopTest {
@Resource(name = "userService")
private UserService u;
@Test
public void fun1() {
u.save();
}
}
注解配置方式
- 通知定义
/**
* 抽取切点
*/
@Pointcut("execution(* cn.probuing.proxy..*ServiceImpl.*(..))")
public void pc() {
}
//前置通知
// |-目标方法运行之前调用
@Before("MyAdvice.pc()")
public void before() {
System.out.println("这是前置通知(注解方式)");
}
//后置通知(如果出现异常)
// |-在目标方法运行之后调用
@AfterReturning("MyAdvice.pc()")
public void afterReturning() {
System.out.println("这是后置通知 出现异常不会调用(注解方式)");
}
//环绕通知
// |-在目标方法之前和之后都调用
@Around("MyAdvice.pc()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知——之前(注解方式)");
//调用目标方法
Object proceed = pjp.proceed();
int i = 1 / 0;
System.out.println("环绕通知——之后(注解方式)");
return proceed;
}
//异常拦截通知
// |-出现异常,调用
@AfterThrowing("MyAdvice.pc()")
public void afterException() {
System.out.println("出现异常(注解方式)");
}
@After("MyAdvice.pc()")
public void afer() {
System.out.println("后置通知,出现异常也会调用(注解方式)");
}
- 配置方式
<?xml version="1.0" encoding="UTF-8"?>
<beans
<!--配置目标对象-->
<bean name="userService" class="cn.probuing.proxy.UserServiceImpl"/>
<!--配置通知对象-->
<bean name="myAdvice" class="cn.probuing.annotationaop.MyAdvice"/>
<!--开启使用注解完成织入-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>