热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

慕课网_《使用GoogleGuice实现依赖注入》学习总结

时间:2017年10月14日星期六说明:本文部分内容均来自慕课网。@慕课网:http:www.imooc.com教学源码:https:github.comzccoderes…学习源

时间:2017年10月14日星期六
说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com
教学源码:https://github.com/zccodere/s…
学习源码:https://github.com/zccodere/s…

第一章:课程介绍

1-1 课程简介

Google Guice:Guice是啥

Guice读音:juice
Guice is a lightweight dependency injection framework for java
Guice 是轻量级的依赖注入框架

Google Guice:说明

Java:一个java的框架、需要有java基础
dependency injection:什么是dependency、剥离dependency、注入dependency
lightweight:轻量级(代码少、易维护、性能优异),跟Spring比较。
但是:学习曲线陡峭、对开发者的要求太高了

课程目标

理解、重新理解dependency injection
掌握Guice的语法,更要掌握Guice的设计理念
开始在你的下一个项目中使用Guice

课程要点

什么是Guice
dependency injection:改造Hello World程序
注入(Injection)
绑定(Binding)
作用域或生命周期(Scope)
Guice AOP
使用Guice和SpringBoot协作搭建一个简单的Web应用
Guice vs Spring

1-2 产生原因

Spring的不足

手动配置:使用xml进行配置,配置太过庞大
自动配置:Spring提供了自动配置,复杂项目无法实现

Guice不同于Spring

取消xml
取消bean的概念
使用Constructor来注入
泛型支持
一个专注于Dependency Injection的框架

参考资料

https://github.com/google/guice/wiki/Motivation
https://github.com/google/guice/wiki/ExternalDocumentation
更多利用英文资料,如Stackoverflow
第二章:理解依赖

2-1 基础配置

Hello Guice

配置Guice环境
Dependency Injection基础
改造Hello World

创建名为guicedemo的maven工程pom如下

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.myimooc
guicedemo
0.0.1-SNAPSHOT
jar
guicedemo
http://maven.apache.org

UTF-8
1.8
1.8
1.8



com.google.inject
guice
4.1.0


com.google.inject.extensions
guice-multibindings
4.1.0



junit
junit
4.12
test



2-2 依赖分析

经典Hello World分析

《慕课网_《使用Google Guice实现依赖注入》学习总结》

核心算法:将指定内容输出至指定目标

改造Hello World程序

面向对象化
消除Dependency
用Guice来配置Dependency

2-3 面向对象

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo;
/**
* @title Applet类
* @describe 提供run()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface MyApplet extends Runnable{}

2.编写HelloWorldPrinter类

package com.myimooc.guicedemo.helloworlddemo;
import com.myimooc.guicedemo.MyApplet;
/**
* @title HelloWorldPrinter类
* @describe 提供打印HelloWorld的功能
* @author zc
* @version 1.0 2017-10-15
*/
public class HelloWorldPrinter implements MyApplet { private void printHelloWorld() {
System.out.println("Hello World!");
} @Override
public void run() {
printHelloWorld();
}
}

3.编写Configuration类

package com.myimooc.guicedemo;
import com.myimooc.guicedemo.helloworlddemo.HelloWorldPrinter;
/**
* @title Configuration类
* @describe 程序启动配置类
* @author zc
* @version 1.0 2017-10-15
*/
public class Configuration { public static MyApplet getMainApplet() {
return new HelloWorldPrinter();
}}

4.编写App类

package com.myimooc.guicedemo;
/**
* @title 启动类
* @describe 改造HelloWorld类
* @author zc
* @version 1.0 2017-10-15
*/
public class App {
/**
* main方法的作用
* bootstrap:
* parse command line:解析命令行参数
* set up environment:配置环境参数
* kick off main logic:启动程序逻辑
* @param args
*/
public static void main(String[] args) {
MyApplet mainApplet = Configuration.getMainApplet();
mainApplet.run();
}
}

面向对象化小结

善于运用IDE提供的重构能力
Ctrl + 1:猜测下一步动作
Ctrl + shift + r:重命名
先写代码,再让其编译通过
先思考确定需要什么,然后再机械性劳动实现
函数命名
从实现角度:精确描述函数干什么
从调用者角度:描述调用者需求
两者不匹配:需要进行抽象的点

2-4 提取依赖

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo.noguice;
/**
* @title MyApplet类
* @describe 提供run()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface MyApplet extends Runnable{}

2.编写StringWritingApplet类

package com.myimooc.guicedemo.noguice.helloworlddemo;
import com.myimooc.guicedemo.noguice.MyApplet;
/**
* @title HelloWorldPrinter类
* @describe 提供打印HelloWorld的功能
* @author zc
* @version 1.0 2017-10-15
*/
public class StringWritingApplet implements MyApplet { private MyDestination destination;
private StringProvider stringProvider; public StringWritingApplet(MyDestination destination,StringProvider stringProvider) {
super();
this.destination = destination;
this.stringProvider = stringProvider;
}
private void writeString() {
destination.write(stringProvider.get());
} @Override
public void run() {
writeString();
}
}

3.编写StringProvider类

package com.myimooc.guicedemo.noguice.helloworlddemo;
/**
* @title StringProvider类
* @describe 提供get()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface StringProvider {
String get();
}

4.编写MyDestination类

package com.myimooc.guicedemo.noguice.helloworlddemo;
/**
* @title MyDestination类
* @describe 提供write()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface MyDestination {
void write(String string);
}

5.编写PrintStreamWriter类

package com.myimooc.guicedemo.noguice.helloworlddemo;
import java.io.PrintStream;
/**
* @title PrintStreamWriter类
* @describe 实现write()方法
* @author zc
* @version 1.0 2017-10-15
*/
public class PrintStreamWriter implements MyDestination {
private PrintStream destination; public PrintStreamWriter(PrintStream destination) {
super();
this.destination = destination;
}
@Override
public void write(String string) {
destination = System.out;
destination.println(string);
}
}

6.编写Configuration类

package com.myimooc.guicedemo.noguice;
import com.myimooc.guicedemo.noguice.helloworlddemo.PrintStreamWriter;
import com.myimooc.guicedemo.noguice.helloworlddemo.StringProvider;
import com.myimooc.guicedemo.noguice.helloworlddemo.StringWritingApplet;
/**
* @title Configuration类
* @describe 程序启动配置类
* @author zc
* @version 1.0 2017-10-15
*/
public class Configuration { public static MyApplet getMainApplet() {
return new StringWritingApplet(
new PrintStreamWriter(System.out),
new StringProvider() {
@Override
public String get() {
return "Hello World";
}
});
}
}

7.编写App类

package com.myimooc.guicedemo.noguice;
/**
* @title 启动类
* @describe 改造HelloWorld类
* @author zc
* @version 1.0 2017-10-15
*/
public class App {
/**
* main方法的作用
* bootstrap:
* parse command line:解析命令行参数
* set up environment:配置环境参数
* kick off main logic:启动程序逻辑
* @param args
*/
public static void main(String[] args) {
MyApplet mainApplet = Configuration.getMainApplet();
mainApplet.run();
}
}

消除Dependency小结

《慕课网_《使用Google Guice实现依赖注入》学习总结》

2-5 配置依赖

代码编写

1.编写MyApplet类

package com.myimooc.guicedemo.useguice;
/**
* @title MyApplet类
* @describe 提供run()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface MyApplet extends Runnable{}

2.编写StringWritingApplet类

package com.myimooc.guicedemo.useguice.helloworlddemo;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.myimooc.guicedemo.useguice.MyApplet;
/**
* @title HelloWorldPrinter类
* @describe 提供打印HelloWorld的功能
* @author zc
* @version 1.0 2017-10-15
*/
public class StringWritingApplet implements MyApplet { private MyDestination destination;
private Provider stringProvider; @Inject
public StringWritingApplet(MyDestination destination,@Output Provider stringProvider) {
super();
this.destination = destination;
this.stringProvider = stringProvider;
}
private void writeString() {
destination.write(stringProvider.get());
} @Override
public void run() {
writeString();
}
}

3.编写MyDestination类

package com.myimooc.guicedemo.useguice.helloworlddemo;
/**
* @title MyDestination类
* @describe 提供write()方法
* @author zc
* @version 1.0 2017-10-15
*/
public interface MyDestination {
void write(String string);
}

4.编写PrintStreamWriter类

package com.myimooc.guicedemo.useguice.helloworlddemo;
import java.io.PrintStream;
import javax.inject.Inject;
/**
* @title PrintStreamWriter类
* @describe 实现write()方法
* @author zc
* @version 1.0 2017-10-15
*/
public class PrintStreamWriter implements MyDestination {
private PrintStream destination; @Inject
public PrintStreamWriter(PrintStream destination) {
super();
this.destination = destination;
}
@Override
public void write(String string) {
destination = System.out;
destination.println(string);
}
}

5.编写Output类

package com.myimooc.guicedemo.useguice.helloworlddemo;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.google.inject.BindingAnnotation;
/**
* @title Output注解
* @describe
* @author zc
* @version 1.0 2017-10-15
*/
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface Output {
}

6.编写HelloWorldModule类

package com.myimooc.guicedemo.useguice.helloworlddemo;
import java.io.PrintStream;
import com.google.inject.AbstractModule;
import com.myimooc.guicedemo.useguice.MyApplet;
/**
* @title HelloWorldModule类
* @describe HelloWorld模块的依赖配置
* @author zc
* @version 1.0 2017-10-15
*/
public class HelloWorldModule extends AbstractModule{ @Override
protected void configure() {
bind(MyApplet.class).to(StringWritingApplet.class);
bind(MyDestination.class).to(PrintStreamWriter.class);
bind(PrintStream.class).toInstance(System.out);
bind(String.class).annotatedWith(Output.class).toInstance("Hello World");
}
}

7.编写MainModule类

package com.myimooc.guicedemo.useguice;
import com.google.inject.AbstractModule;
import com.myimooc.guicedemo.useguice.helloworlddemo.HelloWorldModule;
/**
* @title MainModule类
* @describe Guice用来配置的类
* @author zc
* @version 1.0 2017-10-15
*/
public class MainModule extends AbstractModule{
@Override
protected void configure() {
install(new HelloWorldModule());
}
}

8.编写App类

package com.myimooc.guicedemo.useguice;
import com.google.inject.Guice;
/**
* @title 启动类
* @describe 改造HelloWorld类
* @author zc
* @version 1.0 2017-10-15
*/
public class App {
/**
* main方法的作用
* bootstrap:
* parse command line:解析命令行参数
* set up environment:配置环境参数
* kick off main logic:启动程序逻辑
* @param args
*/
public static void main(String[] args) {
MyApplet mainApplet = Guice
.createInjector(new MainModule())
.getInstance(MyApplet.class);
mainApplet.run();
}
}

Guice配置Dependency小结

《慕课网_《使用Google Guice实现依赖注入》学习总结》

第三章:注入依赖

3-1 基本注入

注入图解

《慕课网_《使用Google Guice实现依赖注入》学习总结》

注入(Injection)

构造函数注入
使用final来区分dependency和状态
注入时不考虑如何实现或绑定
成员变量注入
用于测试
使用injectMembers来注入测试用例

代码编写

1.编写OrderService类

2.编写PaymentService类

3.编写PriceService类

4.编写OrderServiceImpl类

5.编写PaymentServiceImpl类

6.编写PriceServiceImpl类

7.编写SessionManager类

8.编写ServerModule类

9.编写OrderServiceTest类

受篇幅限制,源码请到我的github地址查看

3-2 其他注入

注入Provider

《慕课网_《使用Google Guice实现依赖注入》学习总结》

如何注入Provider

DatabaseConnection dbConn
Provider dbConnProvider
Guice会考虑对象生命周期
需要时可以自己实现Provider

命名注入

@Inject @Named(“dbSpec”) private String dbSpec;
@Inject @LogFileName private String logFileName;
使用@Named:参数来自配置文件或命令行、或者为了开发方便
使用属性:通常采用此方法

代码编写

1.修改SessionManager类

package com.myimooc.guicedemo.server.impl;
import javax.inject.Inject;
import com.google.inject.Provider;
/**
* @title session管理类
* @describe 模拟订单系统
* @author zc
* @version 1.0 2017-10-15
*/
public class SessionManager { private final Provider sessionIdProvider; @Inject
public SessionManager(@SessionId Provider sessionIdProvider) {
super();
this.sessiOnIdProvider= sessionIdProvider;
}
public Long getSessionId() {
return sessionIdProvider.get();
}
}

2.修改ServerModule类

package com.myimooc.guicedemo.server.impl;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.myimooc.guicedemo.server.OrderService;
import com.myimooc.guicedemo.server.PaymentService;
import com.myimooc.guicedemo.server.PriceService;
/**
* @title ServerModule类
* @describe 绑定依赖
* @author zc
* @version 1.0 2017-10-15
*/
public class ServerModule extends AbstractModule{
@Override
protected void configure() {
bind(OrderService.class).to(OrderServiceImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
} @Provides
@SessionId
Long generateSessionId(){
return System.currentTimeMillis();
}
}

3.编写SessionId类

package com.myimooc.guicedemo.server.impl;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.google.inject.BindingAnnotation;
/**
* @title SessionId注解
* @describe 用来绑定数据
* @author zc
* @version 1.0 2017-10-15
*/
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface SessionId {
}

4.编写SessionManagerTest类

package com.myimooc.guicedemo.server.impl;
import static org.junit.Assert.assertNotEquals;
import javax.inject.Inject;
import org.junit.Before;
import org.junit.Test;
import com.google.inject.Guice;
/**
* @title 测试类
* @describe 测试@Provides
* @author zc
* @version 1.0 2017-10-15
*/
public class SessionManagerTest { @Inject
SessionManager sessionManager; @Before
public void setUp(){
Guice.createInjector(new ServerModule())
.injectMembers(this);
} @Test
public void testGetSessionId() throws InterruptedException{
Long sessionId1 = sessionManager.getSessionId();
Thread.sleep(1000);
Long sessionId2 = sessionManager.getSessionId();
assertNotEquals(sessionId1.longValue(), sessionId2.longValue());
}}
第四章:绑定依赖

4-1 绑定详解

绑定图解

《慕课网_《使用Google Guice实现依赖注入》学习总结》

绑定

类名绑定
实例绑定
连接绑定
Provider绑定
命名绑定
泛型绑定
集合绑定

4-2 模块组织

Module的相互关系

并列:Guice.createInjector(module1,module2,…)
嵌套:install(module)
覆盖:Modules.override(module1).with(module2)

Module何时被运行

Module里存放了很多表达式
Module不被“运行”
Guice.createInjector()时记录所有表达式

系统何时初始化

没有“初始化”概念,没有Spring的Configuration Time
injector.getInstance()时根据表达式调用构造函数

4-3 绑定示例

案例:HelloWorld与命令行

让HelloWorld打印命令行参数
让HelloWorld通过命令行决定启动哪个Applet

代码编写

1.编写MyApplet类

2.编写Applets类

3.编写StringWritingApplet类

4.编写PrintLineApplet类

5.编写MyDestination类

6.编写PrintStreamWriter类

7.编写Output类

8.编写Args类

9.编写HelloWorldModule类

10.编写PrintLineModule类

11.编写CommandLineModule类

12.编写MainModule类

13.编写App类

受篇幅限制,源码请到我的github地址查看

第五章:生命周期

5-1 基本介绍

生命周期或作用域

《慕课网_《使用Google Guice实现依赖注入》学习总结》

《慕课网_《使用Google Guice实现依赖注入》学习总结》

选择作用域

默认:适用于:一般实例,stateless,构造速度快
如:Parser、PriceCalulator
Singleton:适用于:stateful的实例,构造速度慢的实例,必须线程安全
如:数据库、网络连接
Session/Request:含有session/request信息的实例、stateful的实例
如:SessionSate

5-2 使用介绍

作用域的使用

作为类或者@Provides方法的属性
在绑定时使用In语句
@Singleton的线程安全性
第六章:切面编程

6-1 面向切面

Guice AOP

符合AOP Alliance的MethodInterceptor接口
MethodInterceptor可用于“Aspects”
获取函数调用类、方法、参数
控制是否执行函数调用

实现AOP

绑定MethodInterceptor
实现MethodInterceptor
在MethodInterceptor中注入Dependency

代码编写

1.编写Logged类

package com.myimooc.guicedemo.aop;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* @title Logged注解
* @describe 用于标识需要记录日志的方法
* @author zc
* @version 1.0 2017-10-15
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Logged {}

2.编写LoggedInterceptor类

package com.myimooc.guicedemo.aop;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import com.google.common.base.Joiner;
/**
* @title LoggedMethodInterceptor类
* @describe 切面类,用于处理被拦截的方法,实现日志记录
* @author zc
* @version 1.0 2017-10-15
*/
public class LoggedInterceptor implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {

// 获得调用参数
invocation.getArguments();
// 获得调用对象
invocation.getClass();
// 获得调用方法
Method method = invocation.getMethod();

// 记录日志
System.out.println(String.format("Calling %s#%s(%s)",
method.getDeclaringClass().getName(),
method.getName(),
Joiner.on(",").join(invocation.getArguments())));

// 执行调用方法
Object result = invocation.proceed();

// 返回调用结果
return result;
}
}

3.编写LoggedModule类

package com.myimooc.guicedemo.aop;
import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;
/**
* @title LoggedModule类
* @describe 用于配置依赖绑定
* @author zc
* @version 1.0 2017-10-15
*/
public class LoggedModule extends AbstractModule{
@Override
protected void configure() {

// 配置拦截任意类,带有@Logged注解修饰的方法
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Logged.class),
new LoggedInterceptor());

}
}
第七章:框架集成

7-1 协作框架

使用Guice与SpringBoot协作搭建Web应用

使用SpringBoot搭建简单的Web应用
使用Guice搭建业务逻辑

协作框架

《慕课网_《使用Google Guice实现依赖注入》学习总结》

7-2 案例实战

创建名为guicespring的maven工程

完成后的项目结构如下

《慕课网_《使用Google Guice实现依赖注入》学习总结》

受篇幅限制,源码请到我的github地址查看

协作小结

SpringBoot进行总控
各自绑定Guice Injector和Spring ApplicationContext
注意对象生命周期
第八章:课程总结

8-1 适用场景

Guice与Spring

Guice不是Spring的重制版
Spring绑定
配置文件体现完整装配结构
大量使用字符串:实例名:属性名
在Config Time完成组装
Guice绑定
Java代码描述绑定规则
每个注入和绑定仅描述局部依赖
没有Config Time

Guice的优点

代码量少
性能优异
支持泛型
Constructor绑定:Immutable objects,不再需要getter/setter
强类型
易于重构

Guice的缺点

Module和绑定规则不易理解
文档教程少,社区资源少
无法方便搭出特殊结构:如循环依赖
Guice仅仅是依赖注入框架,而Spring涵盖较多

从Spring迁移到Guice

不建议
Spring与Guice整合

新项目需要选择Dependency Injection方案

不妨尝试Guice
与其它组件或解决方案整合:注意对象生命周期

8-2 课程回顾

课程回顾

什么是Guce
Dependency Injection:改造Hello World程序
注入(Injection)
绑定(Binding)
作用域或生命周期(Scope)
Guice AOP
使用Guice与SpringBoot协作搭建Web应用

推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 标题: ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • Java源代码安全审计(二):使用Fortify-sca工具进行maven项目安全审计
    本文介绍了使用Fortify-sca工具对maven项目进行安全审计的过程。作者通过对Fortify的研究和实践,记录了解决问题的学习过程。文章详细介绍了maven项目的处理流程,包括clean、build、Analyze和Report。在安装mvn后,作者遇到了一些错误,并通过Google和Stack Overflow等资源找到了解决方法。作者分享了将一段代码添加到pom.xml中的经验,并成功进行了mvn install。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • 使用freemaker生成Java代码的步骤及示例代码
    本文介绍了使用freemaker这个jar包生成Java代码的步骤,通过提前编辑好的模板,可以避免写重复代码。首先需要在springboot的pom.xml文件中加入freemaker的依赖包。然后编写模板,定义要生成的Java类的属性和方法。最后编写生成代码的类,通过加载模板文件和数据模型,生成Java代码文件。本文提供了示例代码,并展示了文件目录结构。 ... [详细]
author-avatar
Zhangjingy2502870421
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有