JAVA配置&注解方式搭建简单的SpringMVC前后台交互系统
前面两篇文章介绍了 基于XML方式搭建SpringMVC前后台交互系统的方法,博文链接如下:
http://www.cnblogs.com/hunterCecil/p/8252060.html
http://www.cnblogs.com/hunterCecil/p/6924935.html
本文重点介绍一下基于java配置+注解方式搭建系统的过程步骤。
一、摘要
1、所需软件列表:
1) tomcat : apache-tomcat-7.0.54 服务端容器
2) Intellij: Intellij IDEA 2016.3.1 开发工具
3) Syslog: SQLyog Community 数据库工具
2. 步骤简述:
1) 新建一个 Java 项目, 按下图依次选择:

2) 项目目录如下:

各目录存储文件如下:
(1)java.com : 目录下用于存放后台代码:
config: 配置启动类
controller: 应用层实现类
dao: 数据访问层的bean
entity: 对象实体类
service: 业务层bean, 具体的数据库操作实现类
(2)resource:
jdbc.properties: 数据库配置
log4j.properties: 日志配置相关属性
users.sql: 建表语句
(3)webapp: 客户端展示相关文件
二、 相关配置文件
1. web.xml配置(用于配置Spring 相关配置项:上下文、日志、字符集、监听器等通过配置文件加载,这里只配置welcome-file-list及session-config)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0" metadata-complete="false"> <!-- session超时 -->
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<!-- 欢迎页面 -->;
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list> </web-app>
2. jdbc. properties
jdbc.driver = com.mysql.jdbc.Driver
db.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
db.username = root
db.password = *****
3. log4j.properties
#日志输出级别
log4j.rootLogger=INFO,stdout,other #设置stdout的日志输出控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#输出日志到控制台的方式,默认为System.out
log4j.appender.stdout.Target = System.out
#设置使用灵活布局
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#灵活定义输出格式
log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n #设置other的日志输出控制台
log4j.appender.other=org.apache.log4j.RollingFileAppender
#设置other的输出日志
log4j.appender.other.File=/WEB-INF/logs/log.log
#设置other的日志最大限制
log4j.appender.other.MaxFileSize=1024KB
#最多只保存20个备份文件
log4j.appender.other.MaxBackupIndex=1000
#输出INFO级别以上的日志
og4j.appender.other.Threshold=INFO
#设置使用灵活布局
log4j.appender.other.layout=org.apache.log4j.PatternLayout
#灵活定义输出格式
log4j.appender.other.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %t %m %n
4. uses.sql
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` tinyint (20),
`name` varchar (90),
`age` tinyint (100),
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of user
-- ----------------------------
insert into `user` (`id`, `name`, `age`) values('2','zhangsan','32');
insert into `user` (`id`, `name`, `age`) values('3','lisi','33');
insert into `user` (`id`, `name`, `age`) values('1','wangwu','12');
5. config目录下文件:
DatabaseConfig
@Configuration
@EnableTransactionManagement
public class DatabaseConfig {
private static final Logger logger = Logger.getLogger(DatabaseConfig.class.getName()); @Value("${jdbc.driver}")
private String jdbcDriver; @Value("${db.url}")
private String dbUrl; @Value("${db.username}")
private String username; @Value("${db.password}")
private String password; @Bean(destroyMethod = "close")
public DataSource dataSource() {
logger.info("mysql url:"+dbUrl);
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(jdbcDriver);
dataSource.setUrl(dbUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
} @Bean
public DataSourceTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
} @Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
return sessionFactory.getObject();
}
}
PropertiesConfig
@Configuration
@PropertySource(value={"classpath:jdbc.properties"})
public class PropertiesConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
RootConfig
@Configuration
@ComponentScan(basePackages = {"com"})
public class RootConfig {
}
WebConfig
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableTransactionManagement
@ComponentScan("com.controller")
@MapperScan("com.dao")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
} @Bean
public StringHttpMessageConverter stringHttpMessageConverter(){
return new StringHttpMessageConverter();
} @Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
return new MappingJackson2HttpMessageConverter();
} @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(stringHttpMessageConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
} /**
* 启用spring mvc 的注解
*/
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
WebAppInitializer
/**
* 配置SpringMVC需要添加DispatchServlet ,
* DispatcherServlet主要负责前端调用URL的分发,
* 它在Web容器初始化的时候被注册。
* 这里配置中继承了DispatchServlet 的一个抽象类AbstractAnnotationConfigDispatcherServletInitializer ,
* 此抽象类的父类在实例化的时候会注册一个DispatchServlet到容器中
* 这里配置了容器初始化时需要加载的配置类 RootConfig,PropertiesConfig 和 WebConfig
*/
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/** 应用上下文、配置文件读取,数据库配置*/
@Override
protected Class<?>[] getRootConfigClasses() {
System.out.println("======1.应用上下文、配置文件读取,数据库配置 load ================");
return new Class<?>[]{RootConfig.class, PropertiesConfig.class, DatabaseConfig.class};
} /* web上下文 */
@Override
protected Class<?>[] getServletConfigClasses() {
System.out.println("======2.web上下文 load ================");
return new Class<?>[]{WebConfig.class};
} /* DispatcherServlet的映射路径 */
@Override
protected String[] getServletMappings() {
System.out.println("======3.DispatcherServlet的映射路径 load ================");
return new String[]{"/"};
} /* 注册过滤器,映射路径与DispatcherServlet一致,路径不一致的过滤器需要注册到另外的WebApplicationInitializer中*/
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[]{characterEncodingFilter};
}
}
6. controller-TestController
@Controller
public class TestController { @Autowired
@Qualifier("userService")
private UserService userService; @RequestMapping(value = "/test", method = RequestMethod.GET)
public String test() {
return "test";
} @RequestMapping(value = "/getuser/{username}", method = RequestMethod.GET)
@ResponseBody
public User getUser(@PathVariable String username) {
return userService.loadUserByUsername(username);
}
}
7. dao-UserDao
@Controller
public class TestController { @Autowired
@Qualifier("userService")
private UserService userService; @RequestMapping(value = "/test", method = RequestMethod.GET)
public String test() {
return "test";
} @RequestMapping(value = "/getuser/{username}", method = RequestMethod.GET)
@ResponseBody
public User getUser(@PathVariable String username) {
return userService.loadUserByUsername(username);
}
}
8. entity-User
public class User {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
9. log-logAspect
@Component
@Aspect
public class LogAspect {
private static final Logger logger = Logger.getLogger(LogAspect.class.getName()); @Pointcut("execution(* com.controller.*.*(..))")
public void performance() {
} @Before("performance()")
public void optionBefore(JoinPoint joinPoint){
System.out.println("@Before开始执行"+joinPoint.getSignature().getDeclaringTypeName() +
"." + joinPoint.getSignature().getName());
} @After("performance()")
public void optionAfter(JoinPoint joinPoint){
System.out.println("@After结束执行"+joinPoint.getSignature().getDeclaringTypeName() +
"." + joinPoint.getSignature().getName());
}
@Around("performance()")
public Object optionAround(ProceedingJoinPoint pjp) throws Throwable {
Object retVal = null;
System.out.println("@Around start..");
try {
retVal = pjp.proceed();
} catch (Throwable ex) {
System.out.println("error in @Around");
throw ex;
}
System.out.println("@Around end");
return retVal;
} @AfterReturning(pointcut = "performance()", returning = "returnValue")
public void optionAfterReturn(JoinPoint joinPoint, Object returnValue) {
System.out.println("@AfterReturning:目标方法为:" +
joinPoint.getSignature().getDeclaringTypeName() +
"." + joinPoint.getSignature().getName());
System.out.println("@AfterReturning:参数为:" +
Arrays.toString(joinPoint.getArgs()));
System.out.println("@AfterReturning:返回值为:" + returnValue);
System.out.println("@AfterReturning:被织入的目标对象为:" + joinPoint.getTarget()); } @AfterThrowing(pointcut = "performance()", throwing = "e")
public void optionError(JoinPoint joinPoint, Throwable e) {
logger.log(Level.WARNING,"异常方法:{" + joinPoint.getTarget().getClass().getName() +
"." + joinPoint.getSignature().getName() + "}" +
"异常类型:{" + e.getClass().getName() + "}" +
"异常信息:{" + e.getMessage() + "}" +
"参数:{" + Arrays.toString(joinPoint.getArgs()) + "}", e);
}
}
10. service-UserService
public interface UserService {
User loadUserByUsername(String username);
void saveUser(User user);
}
11. service-impl-UserServiceImpl
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Transactional(readOnly = true)
public User loadUserByUsername(String username) {
return userDao.loadUserByUsername(username);
}
@Transactional
public void saveUser(User user) {
userDao.saveUser(user);
}
}
12. maven 对应的pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com</groupId>
<artifactId>springJavaConfig</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springJavaConfig Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.6</java.version>
</properties>
<dependencies>
<dependency>
<!--Unit Test -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
</dependencies>
<build>
<finalName>springJavaConfig</finalName>
</build>
</project>
三. 启动过程打印日志:
Connected to server
[2018-01-17 10:47:20,950] Artifact springJavaConfig:war exploded: Artifact is being deployed, please wait...
一月 17, 2018 10:47:23 上午 org.apache.catalina.startup.TldConfig execute
信息: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
======1.应用上下文、配置文件读取,数据库配置 load ================
======2.web上下文 load ================
======3.DispatcherServlet的映射路径 load ================
一月 17, 2018 10:47:24 上午 org.springframework.web.context.ContextLoader initWebApplicationContext
信息: Root WebApplicationContext: initialization started
一月 17, 2018 10:47:24 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
信息: Refreshing Root WebApplicationContext: startup date [Wed Jan 17 10:47:24 CST 2018]; root of context hierarchy
一月 17, 2018 10:47:24 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
信息: Registering annotated classes: [class com.config.RootConfig,class com.config.PropertiesConfig,class com.config.DatabaseConfig]
一月 17, 2018 10:47:25 上午 com.config.DatabaseConfig dataSource
信息: mysql url:jdbc:mysql://10.42.120.201:3306/test?useUnicode=true&characterEncoding=UTF-8
一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
信息: Mapped "{[/test],methods=[GET]}" onto public java.lang.String com.controller.TestController.test()
一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
信息: Mapped "{[/getuser/{username}],methods=[GET]}" onto public com.entity.User com.controller.TestController.getUser(java.lang.String)
一月 17, 2018 10:47:25 上午 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
信息: Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
信息: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Wed Jan 17 10:47:24 CST 2018]; root of context hierarchy
一月 17, 2018 10:47:26 上午 org.springframework.web.context.ContextLoader initWebApplicationContext
信息: Root WebApplicationContext: initialization completed in 2370 ms
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.DispatcherServlet initServletBean
信息: FrameworkServlet 'dispatcher': initialization started
一月 17, 2018 10:47:26 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
信息: Refreshing WebApplicationContext for namespace 'dispatcher-servlet': startup date [Wed Jan 17 10:47:26 CST 2018]; parent: Root WebApplicationContext
一月 17, 2018 10:47:26 上午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
信息: Registering annotated classes: [class com.config.WebConfig]
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
信息: Mapped "{[/test],methods=[GET]}" onto public java.lang.String com.controller.TestController.test()
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
信息: Mapped "{[/getuser/{username}],methods=[GET]}" onto public com.entity.User com.controller.TestController.getUser(java.lang.String)
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
信息: Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
信息: Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Wed Jan 17 10:47:26 CST 2018]; parent: Root WebApplicationContext
一月 17, 2018 10:47:26 上午 org.springframework.web.servlet.DispatcherServlet initServletBean
信息: FrameworkServlet 'dispatcher': initialization completed in 356 ms
[2018-01-17 10:47:26,774] Artifact springJavaConfig:war exploded: Artifact is deployed successfully
[2018-01-17 10:47:26,775] Artifact springJavaConfig:war exploded: Deploy took 5,825 milliseconds
可以看到,WebAppInitializer类中我们的配置类已经按顺序加载过了。
四、 测试
url 输入 http://localhost:8080/getuser/zhangsan,可以查看切面部分打印日志如下:
@Around start..
@Before开始执行com.controller.TestController.getUser
@Around end
@After结束执行com.controller.TestController.getUser
@AfterReturning:目标方法为:com.controller.TestController.getUser
@AfterReturning:参数为:[zhangsan]
@AfterReturning:返回值为:com.entity.User@182bab1a
@AfterReturning:被织入的目标对象为:com.controller.TestController@24b0c989
JAVA配置&注解方式搭建简单的SpringMVC前后台交互系统的更多相关文章
- 使用注解方式搭建SpringMVC
1.以前搭建Spring MVC 框架一般都使用配置文件的方式进行,相对比较繁琐.spring 提供了使用注解方式搭建Spring MVC 框架的方式,方便简洁.使用Spring IOC 作为根容器管 ...
- Spring中,使用Java配置的方式进行依赖注入
之前用spring的时候,只知道使用xml的方式,和使用注解的方式,却一直不知道在spring中,还可以使用Java类的方式进行配置.使用Java类的方式,就可以取代xml和注解.使用Java配置是S ...
- 用ELK搭建简单的日志收集分析系统【转】
缘起 在微服务开发过程中,一般都会利用多台服务器做分布式部署,如何能够把分散在各个服务器中的日志归集起来做分析处理,是一个微服务服务需要考虑的一个因素. 搭建一个日志系统 搭建一个日志系统需要考虑一下 ...
- Koa2+MySQL+VUE+ElementIUI搭建简单的后台管理小系统
如题,前端入坑许久,还是写个小东西出来吧 想要搭建自己的一个后台管理,实现简单的增删改查,看起来很简单 其实是真的简单,没有想的那么难,我也就写了一个月吧, 当然是假的,其实也就每天一两个小时,花了大 ...
- 用Maven搭建简单的SpringMVC框架
本文会详细阐述如何用Maven搭建一个简单的SpringMVC框架 这里就不介绍SpringMVC框架了,咱们直接来搭建 第一步 创建一个Maven的web项目 这里有一个简单的方法 new一个Ma ...
- Java SpringBoot注解方式开启异步支持
package task.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import ...
- SpringMVC学习笔记一:采用注解式搭建简单springMVC环境
搭建的环境使用的是maven项目 项目目录树: 搭建环境使用的jar包,pom.xml文件 <project xmlns="http://maven.apache.org/POM/4. ...
- 基于SpringMVC+Mybatis搭建简单的前后台交互系统
前面博文有一篇 名为基于tomcat+springMVC搭建基本的前后台交互系统(http://www.cnblogs.com/hunterCecil/p/6924935.html),例文中使用了Io ...
- 移动端接口:java写get方式访问数据(springmvc+spring。。。)
很多时候,一个问题想明白,找对点了再去问,这样被问的人也知道怎么给你讲,你也听的明白. 就比如做移动端接口,上去就问 怎么弄接口呀,其实是没找到主要的点上,所以不知道怎么弄,那个点就是手机接口是干嘛的 ...
随机推荐
- IO(文件)处理
一.文件操作 1)介绍: 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件, ...
- 前端 IoC 理念入门
背景 近几年,前端应用(WebApp)正朝着大规模方向发展,在这个过程中我们会对项目拆解成多个模块/组件来组合使用,以此提高我们代码的复用性,最终提高研发效率. 在编写一个复杂组件的时候,总会依赖其他 ...
- BZOJ 1257: [CQOI2007]余数之和sum【神奇的做法,思维题】
1257: [CQOI2007]余数之和sum Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4474 Solved: 2083[Submit][St ...
- [bzoj3910] 火车
一开始看错题了... 求经过的道路数量就求个lca,把路径上的点置为已经过的话,可以写一个并查集,把某个点往上连续已经过的一段点并起来. #include<cstdio> #include ...
- angular2 表单验证
模版式表单 (1) angular遇到form自动接管,不想自动接管,添加ngNoForm,当标签为div时,但想被表单接管,添加ngForm; (2) ngForm可以被模版本地变量引用,以便在模版 ...
- 配置 java web Tomcat
index.jsp-->换为默认的MyEclipse JSP Editor打开方法:window -->Preference-->general-->editors--> ...
- CXF之"@XmlType.name 和 @XmlType.namespace 为类分配不同的名称"错误
CXF 的 wsdl2java.bat 生产的代码,拷贝到目录,进行调研 web service接口时,抛出错误: Exception in thread "main" javax ...
- logback的使用和logback.xml详解
一.logback的介绍 Logback是由log4j创始人设计的另一个开源日志组件,官方网站: http://logback.qos.ch.它当前分为下面下个模块: logback-core:其它两 ...
- Aliase_小白学Python_Day0_前言
听到有老师介绍,说你为什么不把你的学习过程保存下来,一是当做总结,二是作为分享.我想,也对.这算是我的第一个博客,本次想写写我为什么选择学习Python. 很多人都问过我一个问题,行业那么多,你为什么 ...
- IT项目角色标准定义
角色 角色标准定义 项目主管 负责协助项目经理分配资源,确定优先级,协调公司和项目组之间的沟通.保证项目团队一直处于良好的状态中.同时监督项目经理的工作方法,以确保项目以及工件符合公司的发展方向以及用 ...