spring
核心概念
-
耦合度高如何解决
- 使用对象的时候,在程序中不要主动使用 new 产生对象,转换为由外部提供对象
-
IoC( Inversion of Control )控制反转
- 对象的创建控制权由程序转移到 外部, 这种思想成为控制反转
-
Spring 对IoC思想进行了实现
- Spring 提供了一个容器,成为IoC容器,用来充当IoC思想中的 “外部”
- IoC容器负责对象的创建、初始化等一系列工作,被创建或者被管理的对象在IoC容器中统称为 bean
-
目标:充分解耦
- 使用IoC容器管理Bean
- 在IoC容器内将有关依赖关系的bean进行关系绑定 (DI)
AOP案例(注解版)
- 导入aop相关坐标
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<!--说明,spring-aop在spring-context导入时已经导入了,无需额外导入-->
- 定义dao接口和实现类
public interface BookDao{
public void save();
public void update();
}
@Repository
public class BookDaoImpl implements BootDao{
public void save(){
System.out.println(System.currentTimeMillis());
System.out.println("book dao save ...");
}
public void update(){
System.out.println("book dao update ...");
}
}
- 定义通知类,制作通知
public class MyAdvice{
public void before(){
System.out.println(System.currentTimeMillis());
}
}
- 定义切入点
public class MyAdvice{
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
public void pt(){}
// 说明:切入点定义一个不具有实际意义的方法进行,即无参数、无返回值,方法体无实际逻辑
}
- 绑定切入点与同志关系,并制定通知添加到原始链接点的具体执行位置
public class MyAdvice{
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
public void pt(){}
@Before("pt()")
public void before(){
System.out.println(System.currentTimeMillis());
}
}
- 定义通知类受Spring容器管理,并定义当前类为切面类
@Component
@Aspect
public class MyAdvice{
@Pointcut("execution(void com.itheima.dao.BookDao.update())")
public void pt(){}
@Before("pt()")
public void before(){
System.out.println(System.currentTimeMillis());
}
}
- 开启Spring对AOP注解驱动支持
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig(){
}
银行转账----spring事务
- 在业务层接口添加Spring事务管理(接口、类 上添加了,这里面的所有方法都开了事务)
public interface AccountService{
@Transactional
public void transfer(String out,String in,Double money);
}
// 注意:Spring注解式事务添加业务层接口中而不会添加到业务层实现类中,降低耦合
// 注解式事务可以添加到业务方法上表示当前方法开启事务,也可添加到接口上表示当前接口所有方法开启事务所有
- 设置事务管理器
@Bean // spring提供的接口
public platfromTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager ptm = new DataSourceTransactionmanager();// jdbc的事务
ptm.serDataSource(dataSource); // 记得注入dataSource
return ptm;
}
/*
事务管理器要根据实现技术进行选择
MyBatis框架使用的是JDBC事务
*/
- 开启注解式事务驱动
@Configuration
@ComponentScan("com.itherma")
@PropertySource("classpath:jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
@EnableTransactionManagement. // 开启注解式事务驱动
public class SpringConfig{
}
案例:转账业务追加日志
- 在业务层接口上添加Spring事务,设置事务传播行为REQUIRES_NEW(需要新事物)
@Service
public class LogServiceImpl implements LogService{
@Autowired
private LogDao logDao;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void log(String out,String in,Double money){
logDao.log("转账操作由"+out+"到"+in+",金额"+money);
}
}
SpringMVC
入门案例: 基于java实现的MVC模型的轻量级Web框架(表现层框架技术)
-
导入SpringMVC坐标和Servlet坐标
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency>
-
创建SpringMVC控制器类
// 2 定义Controller // 2.1 使用@Controller来定义bean @Controller public class UserController { // 定义一个处理请求的操作 // 2.2 设置当前操作的访问路径 @RequestMapping("/save") // 即可以通过/save 来访问当前操作 // 2.3 设置当前操作的返回类型 @ResponseBody // 把返回的东西整体当作相应的内容,输出在web上 public String save(){ System.out.println("user save ..."); return "{'module':'springmvc'}"; } }
-
初始化SpringMVC环境,设定SpringMVC加载对应的bean
// 3。 创建springmvc的配置文件,加载controller对应的bean @Configuration // 标记为配置类 @ComponentScan("com.niu.controller") // 指定扫谁 public class SpringMvcConfig { }
-
初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求·
// 4. 定义一个servlet容器启动的配置类,在里面加载spring的配置 public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer { // 加载springMVC容器配置 @Override protected WebApplicationContext createServletApplicationContext() { // 创建一个容器 AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); // 现在这个容器还是空的,下面加载配置 ctx.register(SpringMvcConfig.class); // 返回ctx return ctx; } // 设置哪些请求归属springMVC处理 @Override protected String[] getServletMappings() { return new String[]{"/"}; // 所有请求都归springMVC处理 } // 加载spring容器配置 @Override protected WebApplicationContext createRootApplicationContext() { return null; } }
- Controller加载控制与业务bean加载控制
- 名称:@ComponentScan
- 类型:类注解
@Configuration
@ComponentScan(calue = "com.niu",
excludeFilters = @ComponentScan,Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig{
}
// excludeFilters: 排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes)
// includeFilters: 加载指定的bean,需要指定类别(type)与具体项(classes)