JavaEE Day06 Spring
Day06 Spring
spring简介
什么是spring
spring产生于2003年,轻量级javase/ee 一站式开源框架
ejb:javabean
spring在三层架构的地位
- 表示层:spring MVC/struts2
- 业务逻辑层:spring framework
- 数据持久层:mybatis、hibernate、JdbcTemplate
spring的产生背景
- 单一设计原则
- 面向扩展开放,面向修改关闭
- 依赖倒置,不要实体类之间的关联过高,通过接口来实现;
spring的优点
- 方便解耦,简化开发(高内聚,低耦合)
- spring是工厂,负责创建对象以及对象关系的维护;
- 支持aop编程(面向切面编程)
- spring支持对优秀框架的集成
- spring支持对javaee api的简化
- spring支持对junit的整合
spring的体系结构
spring的核心

- ioc:控制反转
- aop:面向切面
入门案例
ioc:控制反转。将对象创建和依赖管理的权限反转给spring、容器。
DI:依赖注入
创建java项目。导入jar
核心容器jar+commons_logging(日志增强)
步骤:
├─applicationContext.xml
├─dao
│ ├─UserDao.java
│ └─impl
│ └─UserDaoImpl.java
├─service
│ ├─UserService.java
│ └─impl
│ └─UserServiceImpl.java
└─test
└─Test.java
- 创建lib目录,导入spring的jar包,spring-beans,spring-context,spring-core,srping_expression(不是javadoc和source),日志文件:导入mybatis中的commons-logging.jar即可
- 创建dao包,在包下创建接口UserDao
- 在dao包下创建impl包,在impl包下创建userDaoImpl实现类,不需要连接数据库,直接打印一段文字即可
- 在src目录下创建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定义在这里 --> <!-- bean:代表配置管理一个对象 id:唯一标识 class:类的完全限定名称 --> <bean id="userdao" class="dao.impl.UserDaoImpl"></bean> </beans> - 新建测试类
此处建议使用接口,方便import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String[] args) { // 创建管理对象权限 ---> 自身 // spring容器先创建和管理dao(配置文件) // 从spring容器中获取dao对象 // UserDao dao = new UserDaoImpl(); ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao dao = ac.getBean("userdao", UserDao.class); dao.addUser(); dao.deleteUser(); } }
对象创建方式
<?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定义在这里 -->
<!-- bean:代表配置管理一个对象
id:唯一标识
class:类的完全限定名称
-->
<bean id="userdao" class="dao.impl.UserDaoImpl"></bean>
<!--调用无参构造+setter方法创建-->
<!--<bean id="userservice" class="service.impl.UserServiceImpl">
<!–给属性赋值 name:属性的名称(setDao方法) value:简单类型值 ref:引用–>
<property name="dao" ref="userdao"></property>
</bean>-->
<!--使用有参构造-->
<bean id="userservice" class="service.impl.UserServiceImpl">
<!--构造器参数: name:参数名称 value:简单类型值 ref:引用 index:参数的索引 type:参数的类型-->
<!--<constructor-arg name="dao" ref="userdao"></constructor-arg>-->
<constructor-arg index="0" ref="userdao"></constructor-arg>
</bean>
</beans>
调用方法
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
import service.UserService;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) {
// 创建管理对象权限 ---> 自身
// spring容器先创建和管理dao(配置文件)
// 从spring容器中获取dao对象
// UserDao dao = new UserDaoImpl();
/*ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = ac.getBean("userdao", UserDao.class);
dao.addUser();
dao.deleteUser();*/
/*UserService service = new UserServiceImpl();
service.addUser();
service.deleteUser();*/
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = ac.getBean("userservice",UserService.class);
service.addUser();
service.deleteUser();
}
}
bean声明周期

目录结构
├─applicationContext.xml
├─pojo
│ └─User.java
└─test
└─Test.java
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="user" class="pojo.User" init-method="init" destroy-method="destory">
<property name="uid" value="1"></property>
</bean>
</beans>
User.java
package pojo;
public class User {
private int uid;
private String username;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void init(){
System.out.println("初始化");
}
public void destory(){
System.out.println("销毁");
}
}
test.java
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.User;
import service.UserService;
import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) {
// 创建管理对象权限 ---> 自身
// spring容器先创建和管理dao(配置文件)
// 从spring容器中获取dao对象
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = ac.getBean("user", User.class);
System.out.println(user);
try {
ac.getClass().getMethod("close").invoke(ac);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
注解实现bean的装配
前提:需要spring-aop.jar
- @Component:创建对象 等价于
- @Compoenet("id"):创建对象 等价于
- @Controller: 表示层创建对象
- @Service:业务逻辑层创建对象
- @Repository:数据持久层创建对象
- @Autowired: 按照类型自动注入(找不到:不注入,找到一个:注入成功,找到多个:报异常),在私有属性上配置
- 按照名称注入
- @Autowired
@qualifier("name") 配置私有属性的名字 - @Resource(name="name")
- @Autowired
步骤
目录结构
├─applicationContext.xml
├─dao
│ ├─UserDao.java
│ └─impl
│ └─UserDaoImpl.java
├─service
│ ├─UserService.java
│ └─impl
│ └─UserServiceImpl.java
└─test
├─Test.java
└─Test2.java
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--schema:通过namespace规范标签-->
<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">
<!-- bean definitions here -->
<!-- 通过包名进行扫描,-->
<context:component-scan base-package="dao,service"></context:component-scan>
</beans>
和不使用注解时一样,只是在创建applicationContext.xml时的配置不同
- 新增context的命名空间
- 追加schemaLocation:context和spring-context.xsd
- 使用context:componenet-scan,扫描所有的主包
UserDao.java
package dao;
public interface UserDao {
void addUser();
void deleteUser();
}
UserDaoImpl.java
package dao.impl;
import dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository("userdao")
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
UserService.java
package service;
public interface UserService {
void addUser();
void deleteUser();
}
UserServiceImpl.java
package service.impl;
import dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import service.UserService;
@Service("userservice")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao dao;
@Override
public void addUser() {
dao.addUser();
}
@Override
public void deleteUser() {
dao.deleteUser();
}
}
Test.java
package test;
import dao.UserDao;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Test {
@Autowired
UserService service;
@org.junit.Test
public void text(){
service.addUser();
service.deleteUser();
}
/*public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// UserDao userdao = ac.getBean("userdao", UserDao.class);
// userdao.addUser();
// userdao.deleteUser();
UserService userservice = ac.getBean("userservice", UserService.class);
userservice.addUser();
userservice.deleteUser();
}*/
}
spring整合junit
Junit:用于单元测试。spring整合junit 在spring-test.jar包中;
- junit使用:导入junit(junit 4)
- ecplise 直接在项目的目录名右击,build-path,add-lib,选择junit
- idea 中,注解@org.junit.Text,然后使用alt+endter,或者使用⌘ Cmd+ Shift+T
代理
对象访问前后实现预处理,过滤等处理
代理模式
静态代理
- 编译期间为每个委托类创建代理类
- 代理类和委托类实现同一个接口
委托类
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
代理类
package service.proxy;
import service.UserService;
/**
* 代理类 静态代理
*/
public class UserServiceProxy implements UserService {
// UserService service = new UserServiceImpl_bak();
UserService service;
public UserServiceProxy(UserService service) {
this.service = service;
}
@Override
public void addUser() {
System.out.println("开启事务");
service.addUser();
System.out.println("提交事务");
}
@Override
public void deleteUser() {
System.out.println("开启事务");
service.deleteUser();
System.out.println("提交事务");
}
}
Text.java
package test;
import service.UserService;
import service.impl.UserServiceImpl_bak;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
/* // 静态代理
@org.junit.Test
public void test(){
// UserService service = new UserServiceImpl_bak();
UserService service = new UserServiceProxy(new UserServiceImpl_bak());
service.addUser();
service.deleteUser();
}
}
动态代理
- 运行期间为每个委托类的对象创建代理对象;
- 采用反射机制
- 接口+实现类(JDK的动态代理)
- 实现类(cglib的动态代理)继承实现
测试类
只需要实现类或者实现类+接口即可
package test;
import service.UserService;
import service.impl.UserServiceImpl_bak;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
/* // 静态代理
@org.junit.Test
public void test(){
// UserService service = new UserServiceImpl_bak();
UserService service = new UserServiceProxy(new UserServiceImpl_bak());
service.addUser();
service.deleteUser();
}*/
// 无侵入式增强
@org.junit.Test
public void test() {
// 1. 创建委托类对象
UserService service = new UserServiceImpl_bak();
// 2. 为委托类对象创建动态代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
service.getClass().getClassLoader(),
service.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
// 手动调用方法 委托类对象
Object obj = method.invoke(service, args);
System.out.println("提交事务");
return obj;
}
}
);
// 3. 为调用代理对象
proxy.addUser();
System.out.println("*************");
proxy.deleteUser();
}
}
aoP
面向切面编程,采用横向抽取方式,在运行阶段将增强代码植入目标对象的思想;底层采用动态代理
aop应用场景
事务管理,日志系统,性能监测,缓存等等。。。。。
aop框架
- Sprin aop(spring-aop,jar)
- Aspectj(aspectj.jar)
- Jboos
Aop的专业术语
- target: 目标对象,添加增强代码的对象,(委托类)
- advice:通知,增强代码 (遵循特定规范的增强代码)
- joinpoint:连接点,目标对象方法
- pointcut:切入点,真正添加增强目录对象的方法
- weaver:织入 增强代码添加到切入点的过程。
- aspect:切面,增强代码和切入点连接形成逻辑面。
aop编程
-
导入jar
- 4+1(spring的核心包,日志包)
- Spring-aop.jar:spring aop框架
- Spring-aspects.jar :aspectj规范
- Aopaliance-1.0.jar:aop联盟(规范通知)
- Aspectjweaver.jar:实现织入
- 导入spring-text。Jar
-
准备一个接口+实现类(委托类)
-
接口:
package service; public interface UserService { void addUser(); void deleteUser(); } -
实现类
package service.impl; import org.springframework.stereotype.Service; import service.UserService; import txAdvice.TxAdvice; public class UserServiceImpl implements UserService { @Override public void addUser() { tx.before(); System.out.println("添加用户"); tx.after(); } @Override public void deleteUser() { tx.before(); System.out.println("删除用户"); tx.after(); } }
-
-
准备一个增强代码(代理类中多余的代码,新增的功能)
package aspect; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; public class MyAspect { public void before(){ System.out.println("开启事务"); } public void after(){ System.out.println("提交事务"); } } -
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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 1. 创建目标类的对象--> <bean id="userservice" class="service.impl.UserServiceImpl_bak_bak"></bean> <!-- 2. 创建增强代码类对象--> <bean id="myaspect" class="aspect.MyAspect"></bean> <!-- 3. 织入增强代码 --> <aop:config> <!-- 配置切入点 expression:excution(返回值 包名.类型.方法名(参数列表)) *: 通配符 返回值 ..* : 包下的以及所有子包下的所有方法 .. : 参数列表任意 --> <aop:pointcut id="myPointcut" expression="execution(* service..*(..))"></aop:pointcut> <!-- 配置切面 ref:增强代码类--> <aop:aspect ref="myaspect"> <!-- 前置增强 mothod:增强代码来的方法名 切入点--> <aop:before method="before" pointcut-ref="myPointcut"/> <!-- 后置增强 --> <aop:after-returning method="after" pointcut-ref="myPointcut"/> </aop:aspect> </aop:config> </beans> -
使用junit4来测试
package test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class Test1 { @Autowired UserService service; @org.junit.Test public void test(){ service.addUser(); service.deleteUser(); } }
apo 注解编程
接口
package service;
public interface UserService {
void addUser();
void deleteUser();
}
实现类
package service.impl;
import org.springframework.stereotype.Service;
import service.UserService;
import txAdvice.TxAdvice;
/**
* 委托类
*/
@Service("userservice")
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
增强代码类
package aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component("myaspect")
@Aspect
public class MyAspect {
// 异常增强
// @AfterThrowing
// 最终增强
// @After
// 环绕增强(必须手动调用目标方法)
// @Around
@Pointcut("execution(* service..*(..))")
public void pointCut(){}
@Before("pointCut()")
public void before(){
System.out.println("开启事务");
}
@AfterReturning("pointCut()")
public void after(){
System.out.println("提交事务");
}
}
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"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="aspect,service"></context:component-scan>
<!-- 自动实现代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
测试类
package test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import service.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Test1 {
@Autowired
UserService service;
@org.junit.Test
public void test(){
service.addUser();
service.deleteUser();
}
}
最好使用java1.8,否则很可能报错


浙公网安备 33010602011771号