Spring ioc aop简单入门
1. 初识spring(Spring.io)
(1) 什么是spring:
Spring框架产生于2003年,轻量级的javase / javaee 一栈式开源框架。
(2) spring优点:
A、方便解耦,简化开发(高内聚,低耦合):
Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理。
B、AOP编程的支持:
Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。
C、声明式事务的支持:
只需要通过配置就可以完成对事务的管理,而无需手动编程。
D、方便程序的测试:
Spring对Junit4支持,可以通过注解方便的测试Spring程序。
E、方便集成各种优秀框架:
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持。
F、降低JavaEE API的使用难度:
Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
(3) Spring的核心(IOC和AOP):
A、IOC(Inversion of Control):控制反转(对象创建的问题);
B、AOP(Aspect Oriented Programming):面向切面编程。
2. Spring的体系结构
3. Spring的入门案例(IOC)
IOC:控制反转
它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。本质就是对象的调用权的转移。(创建对象的权力交给容器)
DI:依赖注入
在运行期,由外部容器动态地将依赖对象注入到另一个对象中。
(1)、开发步骤:
下载:https://repo.spring.io
A、创建项目导入jar:
4+1: beans core context spel + commons-logging
Eclipse:
commons-logging-1.1.1.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
IDEA:
<!-- spring框架包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring框架包 -->
B、创建接口和类:
UserDao:
package spring.ioc.dao;
public interface UserDao {
void addUser();// 添加
void delUser();// 删除
}
UserDaoimpl:
package spring.ioc.impl;
import spring.ioc.dao.UserDao;
public class UserDaoimpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void delUser() {
System.out.println("删除用户");
}
}
UserService:
package spring.ioc.serviceimpl;
import spring.ioc.dao.UserDao;
import spring.ioc.service.UserService;
public class userServiceImpl implements UserService {
// UserDao userDao = new UserDaoimpl();
/*
// 1.setter
UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
*/
// 2.构造器
UserDao userDao;
public userServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void addUser() {
userDao.addUser();
}
@Override
public void delUser() {
userDao.delUser();
}
}
Test1:
package spring.ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.ioc.service.UserService;
public class Test1 {
public static void main(String[] args) {
/*
原始方式创建
*/
/*
UserDao ud = new UserDaoimpl();
ud.addUser();
ud.delUser();
*/
// spring 容器创建对象
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/ioc/applicationContext.xml");
// 获取对象
// 1
// UserDao userDao = ac.getBean("userDao", UserDao.class);
// userDao.addUser();
// userDao.delUser();
// 2
UserService userService = ac.getBean("userService", UserService.class);
userService.addUser();
userService.delUser();
}
}
C、配置文件:
jdbc.properties:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/db_name?characterEncoding=utf8&useSSL=false
db.username=uname
db.password=upass
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean:代表配置管理一个对象
id:唯一标识
class:类的完全限定名称
-->
<!-- 创建 UserDao 对象 -->
<bean id="userDao" class="spring.ioc.impl.UserDaoimpl" />
<!-- 创建 UserService 对象 ioc -->
<bean id="userService" class="spring.ioc.serviceimpl.userServiceImpl" >
<!-- DI setter方式依赖注入 -->
<!-- 给属性赋值 name:属性名称(setDao方法) value:简单类型 ref:引用 -->
<!-- <property name="userDao" ref="userDao"/>-->
<!-- DI 构造器方式依赖注入 -->
<!-- 构造参数 name:参数名称 value:简单类型 ref:引用 index:参数索引 type:参数类型-->
<!-- <constructor-arg name="userDao" ref="userDao" />-->
<constructor-arg index="0" ref="userDao" />
</bean>
</beans>
4. bean的实例化
A、类构造器方式实例化(无参构造,有参构造)
<!-- 调用无参构造+setter方法创建 -->
<bean id ="userservice" class="service.impl.UserServerImpl">
<!-- 给属性赋值 name:属性名称(setDao方法) value:简单类型 ref:引用-->
<property name="dao" ref="userdao"></property>
</bean>
```xml
<!-- 调用有参构造 -->
<bean id="userservice" class="service.impl.UserServerImpl">
<!-- 构造参数 name:参数名称 value:简单类型 ref:引用 index:参数索引 type:参数类型-->
<!-- <constructor-arg name="dao" ref="userdao"></constructor-arg> -->
<constructor-arg index="0" ref="userdao"></constructor-arg>
</bean>
5. 注解实现装配(重)
(1) 创建对象 (beans):
注解要加一个jar包 aop.xxx.jar
@Component (*) ——》
@Controller 表示层创建 SpringMVC
@Service 业务逻辑
@Repository (数据访问 )持久层
(2) 依赖注入DI:
A、@Resource(name=””) 实现依赖注入(按bean名称) jdk注解 不要导成@Resources
B、@Autowired 按类型
C、联合
@Autowired 按类型(*)
@Qualifier(“”) 按名称(缺点不能单独使用) 区别:如果有多个子类,可以通过名字实现
(3) Eclipse导入:spring-aop.jar
IDEA:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
(4) 开发步骤:
UserDao:
package spring.annotation.dao;
public interface UserDao {
void addUser();// 添加
void delUser();// 删除
}
UserDaoimpl:
package spring.annotation.impl;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import spring.annotation.dao.UserDao;
//@Component(value = "userDao")
@Repository(value = "userDao")
public class UserDaoimpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void delUser() {
System.out.println("删除用户");
}
}
UserService:
package spring.annotation.service;
public interface UserService {
void addUser();// 添加
void delUser();// 删除
}
UserServiceImpl:
package spring.annotation.serviceimpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import spring.annotation.dao.UserDao;
import spring.annotation.service.UserService;
import javax.annotation.Resource;
@Service(value = "userService")
public class UserServiceImpl implements UserService {
// @Resource(name = "userDao") //名称 jdk 1
// @Autowired // 类型 (spring.annotation.dao.UserDao 类) 2
@Autowired
@Qualifier(value = "userDao") // 3 实现多个类下,指定其中一个
UserDao userDao;
@Override
public void addUser() {
userDao.addUser();
}
@Override
public void delUser() {
userDao.delUser();
}
}
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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 包扫描 ,搜索注解 -->
<context:component-scan base-package="spring.annotation.impl,spring.annotation.serviceimpl" />
</beans>
Test2:
package spring.annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.annotation.service.UserService;
import spring.annotation.serviceimpl.UserServiceImpl;
public class Test2 {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/annotation/applicationContext.xml");
UserService bean = ac.getBean("userService", UserService.class);
bean.addUser();
bean.delUser();
}
}
6. 代理
访问真实对象之前和之后对请求进行预处理以及过滤等功能。
(1) 静态代理:
在编辑期间为每个真实类创建代理类,在代理类中提供预处理以及过滤功能。
静态代理 ----> 实现同一个接口
真实类(委托类)、代理类
A、接口 UserDao 同上;
B、被代理类 UserDaoimpl 同上;
C、代理类 StaticProxyUserDao:
package spring.annotation.proxy;
import spring.annotation.dao.UserDao;
import spring.annotation.impl.UserDaoimpl;
// 代理类
public class StaticProxyUserDao implements UserDao {
UserDaoimpl userDao;// 被代理类对象
public StaticProxyUserDao(UserDaoimpl userDao) {
this.userDao = userDao;
}
@Override
public void addUser() {
userDao.addUser();// 被代理类方法调用
}
@Override
public void delUser() {
userDao.delUser();// 被代理类方法调用
}
}
D、测试类 TestStaticProxy:
package spring.annotation;
import spring.annotation.impl.UserDaoimpl;
import spring.annotation.proxy.StaticProxyUserDao;
public class TestStaticProxy {
public static void main(String[] args) {
StaticProxyUserDao u = new StaticProxyUserDao(new UserDaoimpl());
u.addUser();
u.delUser();
}
}
缺点:必须给每个接口写代理类。
(2) 动态代理:
在运行期间为每个真实对象创建代理对象的方式。(AOP 学习思想)
A、Jdk动态代理 :接口+ 实现类。
// 接口类
UserDao{
Void addUser()
}
// 被代理类
UserDaoImpl implements UserDao{
Void addUser(){
System.out.println(“添加用户”)
}
}
// JDK 动态代理类
Public class proxyTest{
Public static void main(){
UserDao dao = new UserDaoImpl();
//生成代理对象 (类加载器,委托类实现的接口,)
UserDao proxy = Proxy.newProxyInstance(ProxyTest.class.getclassLoader(),dao.getClass().getInterfaces(), new InvocationHandler(){
//proxy : 代理类对象
//method : 委托类对象方法描述对象
// args 方法参数
public Object invoke(Object proxy,Method method,Object[] args){
//手动调用拦截的方法
System.out.println(“….”)
Object obj= method.invoke(dao,args)
System.out.println(“….”)
return obj;
});
proxy.addUser();
}
}
}
B、Cglib动态代理 委托类(不需要实现接口) asm+cglib.jar
Class userImpl2{
Public void addUser(){
Syso(“添加用户”);
}
}
//测试 必须要导入asm cglib spring-core中有
Main(){
//1.创建委托类对象
UserDaoImpl2 ud = new UserDaoImpl2();
//2创建代理类对象
Enhancer e = new Enhancer();
//设置父类
e.setSuperclass(UserDaoImpl2.class);//创建谁的代理对象
//添加增强功能 创建callback子接口的对象 ctrl+t
e.setCallBack(new MethodInterceptor(){
public object intercept(Object proxy,Method m,Object[] args,MethodProxy mp){
method.invoke(userdao,args);
}
});
UserDaoImpl2 proxy = (UserDaoImpl2)e.create();
//调用
Proxy.addUser();
}
7. Spring AOP
(1) 专业术语:
a.Target:目标对象 需要添加增强代码的类的对象
b.Advice:通知 增强代码
c.Joinpoint:连接点 目标对象的方法
d.Pointcut:切入点 添加增强代码的方法
e.Weaver:织入 增强代码添加到目标对象方法的过程
f.Aspect:切面 通知+ 切点
(2) 导入jar 包:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
(3) 开发步骤:
A、接口类 UserService:
package spring.aop.service;
public interface UserService {
void addUser();
void delUser();
void select();
}
B、实现类 UserServiceImpl:
package spring.aop.service.impl;
import org.springframework.stereotype.Service;
import spring.aop.service.UserService;
//@Service("userService")
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void delUser() {
System.out.println("删除用户");
}
@Override
public void select() { System.out.println("查询用户"); }
}
C、通知类 MyAdvice:
package spring.aop.advice;
public class MyAdvice {
public void before(){
System.out.println("开启事务");
}
public void after(){
System.out.println("结束事务");
}
}
D、配置文件 applicationContext:
<?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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 包扫描 ,搜索注解 -->
<context:component-scan base-package="spring.aop.service" />
<!-- Spring AOP -->
<!-- 目标对象 -->
<bean id="userService" class="spring.aop.service.impl.UserServiceImpl"></bean>
<!-- 通知 -->
<bean id="myAdvice" class="spring.aop.advice.MyAdvice"></bean>
<!--AOP -->
<aop:config>
<!-- 切点 -->
<!--
返回值类型 包名.类名.方法名(参数)
"execution(* spring.aop.service.impl.UserServiceImpl.*User(..))"
"execution(* spring.aop.service.impl..*(..))"
-->
<!-- <aop:pointcut expression="execution(* spring.aop.service.impl..*(..))" id="pc"/>-->
<aop:pointcut expression="execution(* spring.aop.service.impl.UserServiceImpl.*User(..))" id="pc"/>
<!-- 切面 -->
<aop:aspect ref="myAdvice">
<aop:before method="before" pointcut-ref="pc"/>
<aop:after-returning method="after" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
</beans>
E、测试类 TestAOP:
package spring.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.aop.service.UserService;
public class TestAOP {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/aop/applicationContext.xml");
UserService bean = ac.getBean("userService", UserService.class);
bean.addUser();
bean.delUser();
bean.select();
}
}