Solon 2.2.0 | Springboot 2.7.8 | 說明 |
---|---|---|
@Inject * | @Autowired | 注入Bean(by type) |
@Inject("name") | @Qualifier+@Autowired | 注入Bean(by name) |
@Inject("${name}") | @Value("${name}") | 注入設定 |
@Singleton | @Scope(「singleton」) | 單例(Solon 預設是單例) |
@Singleton(false) | @Scope(「prototype」) | 非單例 |
@Import | @Import + @ComponentScan | 設定元件匯入或掃描(一般加在啟動類上) |
@PropertySource | @PropertySource | 設定屬性源(一般加在啟動類上) |
@Configuration | @Configuration | 設定類 |
@Bean | @Bean | 設定Bean |
@Condition | @ConditionalOnClass + @ConditionalOnProperty | 設定條件 |
@Controller | @Controller,@RestController | 控制器類 |
@Remoting | 遠端控制器類(即 Rpc 伺服器端) | |
@Mapping ... | @RequestMapping,@GetMapping... | 對映 |
@Param | @RequestParam | 請求引數 |
@Header | @RequestHeader | 請求頭 |
@Body | @RequestBody | 請求體 |
@Cookie | @CookieValue | 請求Cookie |
@Component | @Component | 普通託管元件 |
@ProxyComponent | @Service,@Dao,@Repository | 代理託管元件 |
@Init * | @PostConstruct | 元件構造完成並注入後的初始化 |
@TestPropertySource | @TestPropertySource | 設定測試屬性源 |
@TestRollback | @TestRollback | 執行測試回滾 |
@SolonMain
public class App{
public static void main(String[] args){
Solon.start(App.class, args);
}
}
@Controller
public class Demo{
@Inject("${app.name}")
String appName;
@Mapping("/")
public Object home(String name){
return appName + ": Hello " + name;
}
}
Solon 2.2.0 | Springboot 2.7.8 | 說明 |
---|---|---|
Context | HttpServletRequest + HttpServletResponse | 請求上下文 |
SessionState | HttpSession | 請求對談狀態類 |
UploadedFile | MultipartFile | 檔案上傳接收類 |
DownloadedFile | 檔案下載輸出類 | |
ModelAndView | ModelAndView | 模型檢視輸出類 |
@Component
public class Demo{
private A a;
private B b;
public Demo(@Inject A a){
this.a = a;
}
public void setB(@Inject B b){
this.b = b;
}
}
@Component
public class Demo{
@Inject
private A a;
@Inject
private B b;
//@Init
//public void initDo(){
// //Solon 的注入是非同步的。想要對注入的 bean 進行實始化,需要借用 @Init 函數
//}
}
或者,可以用 @Configuration + @Bean 進行構建。
@Component
public class Demo{
//注入設定
@Inject("${user.name}")
private String userName;
//手動獲取設定
private String userName = Solon.cfg().get("user.name");
}
各有分工,算有是「剋制」的體現。
@Controller
public class DemoController{
@Db
BaseMapper<UserModel> userService;
@Tran
@Mapping("/user/update")
public void udpUser(long user_id, UserModel user){
userService.updateById(user);
}
}
@Valid
@Controller
public class DemoController {
@NoRepeatSubmit
@NotNull({"name", "icon", "mobile"})
@Mapping("/valid")
public String test(String name, String icon, @Pattern("13\\d{9}") String mobile) {
return "OK";
}
@Whitelist
@Mapping("/valid/test2")
public String test2() {
return "OK";
}
@Mapping("/valid/test3")
public String test3(@Validated UserModel user) {
return "OK";
}
}
@Controller
public class DemoController{
@Db
BaseMapper<UserModel> userService;
@CacheRemove(tags = "user_${user_id}")
@Mapping("/user/update")
public void udpUser(int user_id, UserModel user){
userService.updateById(user);
}
@Cache(tags = "user_${user_id}")
public UserModel getUser(int user_id){
return userService.selectById(user_id);
}
}
//
// 一個資料主從庫的範例
//
@Configuration
public class Config {
@Bean(name = "db1", typed = true)
public DataSource db1(@Inject("${test.db1}") HikariDataSource dataSource) {
return dataSource;
}
@Bean("db2")
public DataSource db2(@Inject("${test.db2}") HikariDataSource dataSource) {
return dataSource;
}
}
//範例:客製化統一輸出控制基礎類別,並統一開啟驗證
//
@Valid
public class ControllerBase implements Render {
@Override
public void render(Object obj, Context ctx) throws Throwable {
if (obj == null) {
return;
}
if (obj instanceof String) {
ctx.output((String) obj);
} else {
if (obj instanceof ONode) {
ctx.outputAsJson(((ONode) obj).toJson());
} else {
if (obj instanceof UapiCode) {
//此處是重點,把一些特別的型別進行標準化轉換
//
UapiCode err = (UapiCode) obj;
obj = Result.failure(err.getCode(), UapiCodes.getDescription(err));
}
if (obj instanceof Throwable) {
//此處是重點,把異常進行標準化轉換
//
Throwable err = (Throwable) obj;
obj = Result.failure(err.getMessage());
}
ctx.outputAsJson(ONode.stringify(obj));
}
}
}
}
@Mapping("/demo/")
@Controller
public class DemoController {
@Mapping("hello")
public void hello(HttpServletRequest req, HttpServletResponse res){
}
}
@Configuration
public class DemoConfiguration implements ServletContainerInitializer{
@Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
//...
}
}
@WebFilter("/demo/*")
public class DemoFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
res.getWriter().write("Hello,我把你過濾了");
}
}
//[伺服器端]
@Socket
@Mapping("/demoe/rpc")
@Remoting
public class HelloRpcServiceImpl implements HelloRpcService {
public String hello(String name) {
return "name=" + name;
}
}
//[使用者端]
var rpc = SocketD.create("tcp://localhost:28080", HelloRpcService.class);
System.out.println("RPC result: " + rpc.hello("noear"));
//[伺服器端]
@Socket
@Mapping("/demoe/rpc")
@Remoting
public class HelloRpcServiceImpl implements HelloRpcService {
public String hello(String name) {
//
//[伺服器端] 呼叫 [使用者端] 的 rpc,從而形成單連結雙向RPC
//
NameRpcService rpc = SocketD.create(Context.current(), NameRpcService.class);
name = rpc.name(name);
return "name=" + name;
}
}
//[伺服器端]
@ServerEndpoint
public class ServerListener implements Listener {
@Override
public void onMessage(Session session, Message message) {
if(message.flag() == MessageFlag.heartbeat){
System.out.println("伺服器端:我收到心跳");
}else {
System.out.println("伺服器端:我收到:" + message);
//session.send(Message.wrapResponse(message, "我收到了"));
}
}
}
//[使用者端]
var session = SocketD.createSession("tcp://localhost:28080");
session.send("noear");
//session.sendAndCallback("noear", (rst)->{}); //傳送並非同步回撥
//var rst = session.sendAndResponse("noear"); //傳送並等待響應
System.out.println(rst);
//[使用者端]
@ClientEndpoint(uri = "tcp://localhost:28080")
public class ClientListener implements Listener {
@Override
public void onMessage(Session session, Message message) {
//之後,就等著收訊息
System.out.println("使用者端2:我收到了:" + message);
}
}
//[定義介面],一般情況下不需要加任何註解
//
public interface UserService {
UserModel getUser(Integer userId);
}
//[伺服器端] @Remoting,即為遠端元件
//
@Mappin("user")
@Remoting
public class UserServiceImpl implements UserService{
public UserModel getUser(Integer userId){
return ...;
}
}
//[消費端]
//
@Mapping("demo")
@Controller
public class DemoController {
//直接指定伺服器端地址
@NamiClient("http://localhost:8080/user/")
UserService userService;
//使用負載
@NamiClient(name="local", path="/user/")
UserService userService2;
@Mapping("test")
public void test() {
UserModel user = userService.getUser(12);
System.out.println(user);
user = userService2.getUser(23);
System.out.println(user);
}
}
/**
* 定義一個負載器(可以對接發現服務)
* */
@Component("local")
public class RpcUpstream implements LoadBalance {
@Override
public String getServer() {
return "http://localhost:8080";
}
}
public class XPluginImp implements Plugin {
@Override
public void start(AopContext context) {
context.beanBuilderAdd(ProxyComponent.class, (clz, bw, anno) -> {
BeanProxy.binding(bw);
});
}
}
src/main/resources/META-INF/solon/solon.aspect.properties
solon.plugin=org.noear.solon.aspect.XPluginImp
//[收集異常](不建議業務使用)
EventBus.push(err);
//[訂閱異常]
EventBus.subscribe(Throwable.class,(event)->{
event.printStackTrace();
});
//或通過SolonApp訂閱
app.onEvent(Throwable.class, (err)->{
err.printStackTrace();
});
//或通過元件訂閱
@Component
public class ErrorListener implements EventListener<Throwable> {
@Override
public void onEvent(Throwable err) {
err.printStackTrace();
}
}
//
// 外掛開發時,較常見
//
SqlManagerBuilder builder = new SqlManagerBuilder(ds);
EventBus.push(builder);
Solon.context().beanBuilderAdd(Controller.class, (clz, bw, anno) -> {
//內部實現,可參考專案原始碼 //構建器,可以獲取型別並進行加工
new HandlerLoader(bw).load(Solon.global());
});
//效果
@Controller
public class DemoController{
}
Solon.context().beanInjectorAdd(Inject.class, ((fwT, anno) -> {
//內部實現,可參考專案原始碼 //注入器,可以根據目標生成需要的資料並賦值
beanInject(fwT, anno.value(), anno.autoRefreshed());
}));
//效果
@Controller
public class DemoController{
@Inject
UserService userService;
}
//攔截器,可以獲取執行動作鏈
Solon.context().beanAroundAdd(Tran.class, new TranInterceptor(), 120);
//效果
@ProxyComponent
public class UserService{
@Tran
public void addUser(User user){
}
}
//內部實現,可參考專案原始碼 //提取器,可以提取被註解的函數
Solon.context().beanExtractorAdd(CloudJob.class, CloudJobExtractor.instance);
//效果 //提取器只對元件有效
@Component
public class Job{
@CloudJob
public void statUserJob(){
}
}