IOC(控制反转、依赖注入)
IOC这种思想,是说,我把一个类它的实现写在一个单独的地方,在用到的地方,用一个最简单的方式把它注入进来。(比如Spring中就是使用的@Autowired)
然后就会在整个容器中去找,谁已经注册为一个toutiao.service。
发现有一个对象,它就把这俩这连起来。
这样,就不会被初始化的顺序啊,类与类之间的依赖啊所困扰。
写完之后只需要注入进来就可以了。
我们首先定义一个ToutiaoService,里面定义一个say的方法,返回一串字符串“This is from ToutiaoService”。
package com.test.service;
import org.springframework.stereotype.Service;
@Service
public class ToutiaoService {
public String say(){
return "This is from ToutiaoService";
}
}
这里附上整个IndexController的代码:
package com.test.controller;
import com.nowcoder.model.User;
import com.nowcoder.service.ToutiaoService;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;
@Controller
public class IndexController {
private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
@Autowired
private ToutiaoService toutiaoService;
@RequestMapping(path = {"/", "/index"})
@ResponseBody
public String index(HttpSession session){
logger.info("Visit Index");
return "Hello nowcoder" + session.getAttribute("msg")
+ "</br>Say:" + toutiaoService.say();
}
@RequestMapping(value = {"/profile/{groupId}/{userId}"})
@ResponseBody
public String profile(@PathVariable("groupId") String groupId,
@PathVariable("userId") int userId,
@RequestParam(value = "type", defaultValue = "1")int type,
@RequestParam(value = "key", defaultValue = "nowcoder") String key){
return String.format("GID{%s}, UID{%d}, TYPE{%d}, KEY{%s}", groupId, userId, type, key);
}
@RequestMapping(value = {"/vm"})
public String news(Model model){
model.addAttribute("value1", "vv1");
List<String> colors = Arrays.asList(new String[]{"RED", "GREEN", "YELLOW", "BLUE"});
Map<String, String> map = new HashMap<String, String>();
for(int i = 0; i < 4; i++){
map.put(String.valueOf(i), String.valueOf(i * i));
}
model.addAttribute("colors", colors);
model.addAttribute("map", map);
model.addAttribute("user", new User("Jim"));
return "news";
}
@RequestMapping(value = {"/request"})
@ResponseBody
public String request(HttpServletRequest request,
HttpServletResponse response,
HttpSession session){
StringBuilder sb = new StringBuilder();
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()){
String name = headerNames.nextElement();
sb.append(name + ":" + request.getHeader(name) + "<br>");
}
for(Cookie cookie : request.getCookies()){
sb.append("Cookie:");
sb.append(cookie.getName());
sb.append(":");
sb.append(cookie.getValue());
sb.append("<br>");
}
sb.append("getMethod: " + request.getMethod() + "<br>");
sb.append("pathInfo: " + request.getPathInfo() + "<br>");
sb.append("getQueryString: " + request.getQueryString() + "<br>");
sb.append("getRequestURI: " + request.getRequestURI() + "<br>");
return sb.toString();
}
@RequestMapping(value = {"/response"})
@ResponseBody
public String response(@CookieValue(value = "nowcoderid", defaultValue = "a") String nowcoderId,
@RequestParam(value = "key", defaultValue = "key") String key,
@RequestParam(value = "value", defaultValue = "value")String value,
HttpServletResponse response){
response.addCookie(new Cookie(key, value));
response.addHeader(key, value);
return "NowCoderId From Cookie: " + nowcoderId;
}
@RequestMapping("/redirect/{code}")
public String redirectView(@PathVariable("code") int code,
HttpSession session){
/*RedirectView red = new RedirectView("/", true);
if(code == 301){
red.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
}
return red;
*/
session.setAttribute("msg", "jump from direct");
return "redirect:/";
}
@RequestMapping("/admin")
@ResponseBody
public String admin(@RequestParam( value = "key", required = true)String key){
if("admin".equals(key)){
return "hello admin";
}
throw new IllegalArgumentException("Key 错误");
}
@ExceptionHandler()
@ResponseBody
public String error(Exception e){
return "error:" + e.getMessage();
}
}
AOP(面向切面)
只要不是一个特殊的服务,面向所有服务要做一个切下来的业务的时候,就可以通过这个面向切面的思路来编码。
当需要打印日志,控制访问权限的时候,可以采用这种方法。
我的目的是希望在执行这个方法之前或者是之后可以调用这个方法来打印相关的日志。
在这个类中,首先定义一个Logger变量。这个Logger有info、warn等方法,可以根据需求来使用。
然后定义在方法前需要打印的信息,以及在方法后需要打印的信息。写Before还有After方法,里面根据需求来写一些调用的方法。
比如这个beforeMethod中,准备一个字符串,然后把每次访问的目标方法的参数给添加到这个字符串中。在日志打印的时候,打印出“Before Method:” + 相关参数。
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Before("execution(* com.nowcoder.controller.*Controller.*(..))")
//这里采用的是通配符的形式,就是只要是带有Controller为后缀的,
//在调用的时候,都可以打印出相关日志。该日志包含目标方法的参数。
public void beforeMethod(JoinPoint joinPoint){
StringBuilder sb = new StringBuilder();
for(Object arg:joinPoint.getArgs()){
sb.append("arg" + arg.toString() + "|");
}
logger.info("before method: " + sb.toString());
}
@After("execution(* com.nowcoder.controller.*Controller.*(..))")
public void afterMethod(JoinPoint joinPoint){
logger.info("after mrthod");
}
}
我们在Controller中添加这个Logger变量,这样就可以打印日志:
当访问这个网站的时候,
再查看控制台,得到输出的日志: