一、使用注解配置Spring
1、添加约束
2、导包
3、开启使用注解代理配置文件
4、将对象注册到容器
@Component注解衍生注解(功能一样)取代<bean class="">
@Repository :dao层
@Service:service层
@Controller:web层
@Repository :dao层
@Service:service层
@Controller:web层
5、修改对象作用域
//指定对象的作用域(类前)
@Scope(scopeName="prototype")
@Scope(scopeName="prototype")
6、值类型的注入
@value 注入属性值
1、加在成员变量上:通过反射的Field赋值(破坏对象的封装性)
1、加在成员变量上:通过反射的Field赋值(破坏对象的封装性)
@Value("沙和尚")
private String name;
2、加在set方法上:通过set方法赋值(推荐使用)
@Value("tom")
public void setName(String name) {
this.name = name;
}
7、引用类型注入
方式一:
@Autowired//自动装配
//问题:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象
private Car car;
方式二:
@Autowired//自动装配
//问题:如果匹配多个类型一致的对象,将无法选择具体注入哪一个对象
@Qualifier("car2")//使用@Qualifier注解告诉spring自动装配哪一个名称的对象
private Car car;
方式三:(推荐)
@Resource(name="car2")//手动注入,指定注入哪个名称的对象
private Car car;
8、初始化|销毁方法
}
@PostConstruct //在对象被创建后调用 相当于init-method
public void init() {
System.out.println("init......");
}
@PreDestroy //在销毁之前调用 相当于destroy-method
public void destroy() {
System.out.println("destroy......");
}
二、安装STS插件
百度三、Spring与junit整合测试
1、导包
spring-test-4.3.9.RELEASE.jar
2、配置注解
3、测试
四、Spring中的AOP
1、概念
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP 最早由 AOP 联盟的组织提出的,制定了一套规范.Spring 将 AOP 思想引入到框架中,必须遵守 AOP 联盟
的规范
的规范
2、为啥学习AOP
对程序进行增强:不修改源码的情况下. AOP 可以进行权限校验,日志记录,性能监控,事务控制.
3、底层实现
代理机制:
* Spring 的 AOP 的底层用到两种代理机制:
* Spring 的 AOP 的底层用到两种代理机制:
* JDK 的动态代理 :针对实现了接口的类产生代理.
* Cglib 的动态代理 :针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类
的子类对象.
* Cglib 的动态代理 :针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类
的子类对象.
4、Spring底层AOP的实现原理(了解)
(1)JDK动态代理增强一个类中方法
(2)JDK动态代理增强一个类中方法
5、AOP名词
五、Spring演示
1、XML配置
(1)导包
(2)准备目标对象
UserServiceImpl.java
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("保存用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void find() {
System.out.println("查找用户");
}
}
(3)准备通知
MyAdvice.java
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)配置进行织入,将通知织入目标对象中
导入约束
applicationContext.xml
<?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="userServiceTarget" class="com.sh.service.UserServiceImpl"></bean>
<!-- 2.配置通知对象 -->
<bean name="myAdvice" class="com.sh.d_springaop.MyAdvice"></bean>
<!-- 3.配置将通知织入目标对象 -->
<aop:config>
<!-- 配置切入点
public void com.sh.service.UserServiceImpl.add()
void com.sh.service.UserServiceImpl.add()
* com.sh.service.UserServiceImpl.add()
* com.sh.service.UserServiceImpl.*()
* com.sh.service.*ServiceImpl.*(..)
* com.sh.service..*ServiceImpl.*(..)
-->
<!-- id:给配置的切点取名 -->
<aop:pointcut expression="execution(* com.sh.service.*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>
测试
Demo.java
//帮我们创建容器
@RunWith(SpringJUnit4ClassRunner.class)
//指定创建容器时使用哪个配置文件
@ContextConfiguration("classpath:com/sh/d_springaop/applicationContext.xml")
public class Demo {
//将名为user的对象注入到u变量中
@Resource(name="userService")
private UserService us;
@Test
public void fun1() {
us.add();
}
}
2、注解配置
(1)导包
(2)准备目标对象
(3)准备通知
前三步和XML配置一致
(4)配置进行织入,将通知织入目标对象中
applicationContext.xml
<?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.sh.service.UserServiceImpl"></bean>
<!-- 2.配置通知对象 -->
<bean name="myAdvice" class="com.sh.e_annotationaop.MyAdvice"></bean>
<!-- 3.开启使用注释完成织入 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
MyAdvice.java
@Aspect
//表示该类是一个通知类
public class MyAdvice {
/**
* 前置通知
* |-目标方法运行之前调用
* 后置通知(如果出现异常不会调用)
* |-目标方法运行之后调用
* 环绕通知
* |-目标方法之前和之后调用
* 异常拦截通知
* |-如果出现异常就会调用
* 后置通知(无论是否出现异常都会调用)
* |-目标方法运行之后调用
*/
@Pointcut("execution(* com.sh.service.*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();//调用目标方法
System.out.println("这是环绕通知之后的部分");
return proceed;
}
//异常通知
@AfterThrowing("MyAdvice.pc()")
public void afterException() {
System.out.println("出现异常了");
}
//后置通知
@After("MyAdvice.pc()")
public void after() {
System.out.println("这是后置通知(出现异常也会调用)");
}
}
参考源码:https://github.com/AmazeLee/Spring.git
If you focus on what you left behind you will never see what lies ahead!
如果你只顾回头看,永远也看不见前方有什么。