一.Spring概述
二.Ioc的原理和定义
三.使用Spring Ioc进行设值注入
四.编写Bean实现动态组装的打印机
五.配置Bean实现动态组装的打印机
六.AOP的定义和原理
七.自动的系统日志功能
一.Spring概述
Spring是个面向Bean的编程
Spring两大核心技术
控制反转(Ioc:Inversion of control)/依赖注入(DI:Dependency Injection)
面向切面编程(AOP:Aspect Oriented Programming)
Beans,Core,Context,把对象封装在Bean里面,而对象里面无非就是数据,Context就是为这个数据提供生存和运行的环境,它可以发现对象与对象的关系,并且建立和维护这些关系。core就是为context的运行提供一些工具类。
二.Ioc的原理和定义
问题:什么是控制反转?
将组件对象的控制权从代码本身转移到外部容器。
.组建化的思想:分离关注点,使用接口,不再关注实现。
目的:解耦合。实现每个组件时,只关注组件内部的事情。
好处:
1.解耦性。
比如A类要调用B类,需要new B().还有可能C类调用B类。或者D类调用B类。如果B类业务一改变,就需要关心B类的实现。如果构造方法做了修改。那么就要到所有的有关地方进行修改。
2.扩展性好。
B类封装的mysql的一些方法。现在想用oracle。那么A类就需要知道oracle的知识。
用工厂返回对象实例,可以解决上面两个问题。
工厂模式:根据我们提供的所需的对象实例的描述,为我们返回所需的产品
1.产品的规范。2产品。3,工厂。4,客户端/调用。
三.使用Spring Ioc进行设值注入
搜索jar包在,浏览器地址栏中输入repo.spring.io,回车。
<bean id="" class="">
<property name="who"><!--和set方法后面的名字对应着-->
<value>ddd</value>
</property>
</bean>
ApplicationContext context = new ClassPathXmlApplicaitonContext("ApplicationContext.xml");//这个要放在classpath的根路径下面
四.编写Bean实现动态组装的打印机
AOP的定义和原理
AOP原理
将复杂的需求分解出不同方面,将公共功能集中解决。
采用代理机制组装起来来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能。
所谓的面向切面编程,是一种通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态添加功能的技术。
AOP相关术语
1.增强处理(Advice)
>前置增强
>后置增强
>环绕增强,异常抛出增强,最终增强等类型
2.切入点(Pointcut)
3.连接点(Join Point)
4.切面(Point)
5.目标对象(Target object)
6.AOP代理(AOP proxy)
7.织入(Weaving)
定义切入点
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public void addNewUser(entity.User))"/>
</aop:config>
表达式匹配规则举例
public * addNewUser(entity.User): "*"表示匹配所有类型的返回值
public void *(entity.User): "*" 表示匹配所有方法名
public void addNewUser(..): ".."表示匹配所有参数个数和类型
* com.service.*.*(..):匹配com.service包下所有类的所有方法
* com.service..*.*(..):匹配com.service 包及其子包下所有类的所有方法。
五.配置Bean实现动态组装的打印机
目标方法
package service.impl;
import service.UserService;
import dao.UserDao;
import entity.User;
/**
* 用户业务类,实现对User功能的业务管理
*/
public class UserServiceImpl implements UserService {
// 声明接口类型的引用,和具体实现类解耦合
private UserDao dao;
// dao 属性的setter访问器,会被Spring调用,实现设值注入
public void setDao(UserDao dao) {
this.dao = dao;
}
public void addNewUser(User user) {
// 调用用户DAO的方法保存用户信息
dao.save(user);
}
}
增强处理
package aop;
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
/**
* 增强处理类
* @author Administrator
*
*/
public class UserServiceLogger {
//日志输出
private static final Logger log = Logger.getLogger(UserServiceLogger.class);
/**
* 前置增强
* JointPoint.getArgs():连接点方法参数数组。
* JointPoint.getTarget():连接点的目标对象。
* JointPoint.getSignature():连接点的方法信息。
* @param jp:连接点对象
*/
public void before(JoinPoint jp) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
/**
* 后置增强
* @param jp:连接点对象
* @param result:目标方法的返回值,
*/
public void afterReturning(JoinPoint jp, Object result) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
+ " 方法。方法返回值:" + result);
}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<bean id="dao" class="dao.impl.UserDaoImpl"></bean>
<bean id="service" class="service.impl.UserServiceImpl">
<property name="dao" ref="dao"></property>
</bean>
<!-- 声明增强方法所在的Bean -->
<bean id="theLogger" class="aop.UserServiceLogger"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 定义切入点 -->
<aop:pointcut id="pointcut"
expression="execution(public void addNewUser(entity.User))" />
<!-- 引用包含增强方法的Bean -->
<aop:aspect ref="theLogger">
<!-- 将before()方法定义为前置增强并引用pointcut切入点 -->
<aop:before method="before" pointcut-ref="pointcut"></aop:before>
<!-- 将afterReturning()方法定义为后置增强并引用pointcut切入点 -->
<!-- 通过returning属性指定为名为result的参数注入返回值 -->
<aop:after-returning method="afterReturning"
pointcut-ref="pointcut" returning="result" />
</aop:aspect>
</aop:config>
</beans>
测试
@Test
public void aopTest() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) ctx.getBean("service");
User user = new User();
user.setId(1);
user.setUsername("test");
user.setPassword("123456");
user.setEmail("test@xxx.com");
service.addNewUser(user);
}
输出结果:
05-12 16:23:39[INFO]aop.UserServiceLogger
-调用 service.impl.UserServiceImpl@2c35e847 的 addNewUser 方法。方法入参:[entity.User@6fd83fc1]
保存用户信息到数据库
05-12 16:23:39[INFO]aop.UserServiceLogger
-调用 service.impl.UserServiceImpl@2c35e847 的 addNewUser 方法。方法返回值:null