28 noiembrie 2022

Spring 5 Fundamentals - ziua 3

Configurări XML

Încă există = se pot folosi. Unele lucruri sunt mai simple cu XML. Se poate separa mai bine de restul codului.

----  application-context.xml  ----

<beans xmlns="" xmlns:xi="" xsi:schemaLocation="">

  <bean name="" class="cale_completă_către_implementare" >
    <property name="speakerRep" ref="speakerRep"> </property>   <!-- setter injection: name definește care setter, iar ref valoarea parametrului (definit mai sus, ca alt bean)  -->
  </bean>

  <bean name="" class="cale_completă_către_implementare" >
    <constructor-arg index="0" ref="speakerRep"> </constructor-arg>   <!-- constructor injection -->
  </bean>

</beans>


 Beans 
  • în esență sunt clase
  • înlocuiesc ce urmează după new 
  • se obțin tot cu appContext.getBean(...)

 Autowiring 
  • byType - face wire cu o instanță de tipul cerut (trebuie să fie unică)
  • byName - face wire după numele bean-ului
  • constructor
  • no (nu dă voie să se facă autowiring)

  <bean name="" class="cale_completă_către_implementare"  autowire="constructor">
  </bean>


Factory Bean


 SpEL  = Spring Expression Language - folosit mai mult în librării 

@Value ("#{ T(java.lang.Math.random() * 100) }")  // se determină la runtime, util în chestiuni de securitate
private double seedNum;


Spring AOP Proxies


 Bean Profiles  

@Repository("speakerRepository")
@Profile("dev")
public class HibernateSpeakerRepositoryImpl implements SpeakerRepository {
  . . .
}


VM option: -Dspring.profiles.active=dev
Altfel, bean-ul nu este disponibil. 

23 noiembrie 2022

Spring 5 Fundamentals - ziua 2

5 scopes

  • Singleton: un singur bean (o singură instanță per container Spring), este scopul prestabilit
  • Prototype: un bean nou (instanță) la fiecare request = opusul lui Singleton
  • Request: un bean la fiecare request http
  • Session: un bean la fiecare sesiune 
  • Global: un bean per aplicație (racordat la durata aplicației, și nu a vizitei mele în aplicație)

Singleton, prototype --> în orice configurație

Request, session, global --> doar în proiecte web


@Service("customerService")

@Scope("singleton")

public class CustomerServiceImpl ...


sau

@Bean(name = "customerRepository")

@Scope(value = BeanDefinition.SCOPE_SINGLETON) // BeanDefinition.SCOPE_PROTOTYPE

public CustomerRepository getCustomerRepository() { ... }


@Autowired

Adnotarea poate fi deasupra setter-ului = injectează bean-ul. Poate fi și în constructor.

Fully autowired - cu stereotipuri: 
  • @Component - echivalentul unui bean la nivel de clasă
  • @Repository
  • @Service (cu sensul că găzduiește business logic)
  • @Controller (pentru creare de servicii web sau microservicii)

@Repository("speakerRepository")
public class HibernateSpeakerRepositoryImpl implements SpeakerRepository {
  . . .
}


@Service("speakerService")
public class SpeakerServiceImpl implements SpeakerService {
  . . .
}


@Configuration
@ComponentScan( {"com.application.path"} )
public class AppConfig {
  // nu mai este nevoie de declarare beans
}

22 noiembrie 2022

Spring 5 Fundamentals - notițe ziua 1

Spring = JEE, POJO based (plain old java object), construit în jurul conceptelor considerate best practice

WORA = write once run anywhere

Spring este folosit pentru a nu mai scrie cod de configurare în aplicație => mai citeț, mai ușor de testat.


Diferențe Spring 5 față de versiuni anterioare:

  • lipsește applicationContext.xml
  • configurări din Java direct în loc de xml-uri


Transformare în proiect Spring:

@Configuration  // înlocuitorul pt applicationContext.xml

public class AppConfig {


  // un bean rămâne „înregistrat” în Spring => este un singleton

  // name e opțional 

  // aplicabil doar la nivel de metodă, nu și de clasă


  @Bean(name = "customerRepository")   

  public CustomerRepository getCustomerRepository() {

    CustomerRepository cust  = new CustomerRepositoryImpl();

    cust.setCustomerAttr(getCustomerAttr());   // setter injection

    return cust;

  }


  @Bean(name = "customerAttr")

  public CustomerAttr getCustomerAttr() {

    return new ... ();

  }

}


public class Application {

  public static void main(String args[]) {

    ApplicationContext appContext = new AnnotationConfigApplicationContext(AppConfig.class);

    CustomerRepository custRepo = appContext.getBean("customerRepository", CustomerRepository.class);

    // do something with custRepo

  }

}


Alternativă la setter injection ----> constructor injection

15 noiembrie 2022

Maven - ziua 2 (finală)

 























Plugins

Goals = plugin-uri configurabile; se pot suprascrie
Exemple: clean, compile, etc

Phases:
  • validate
  • compile
  • test
  • package
  • integration-test nou!
  • verify - verifică integritatea
  • install - instalează pachetul în repo local
  • deploy - copiază pachetul într-un repo remote











JAR plugin - configurat automat ca parte a fazei package, dar se poate suprascrie. Se pot configura atât ce trebuie inclus cât și exclus.













> mvn package   // descarcă tot ce este nevoie în proiect, creează un jar 


Source plugin - parte din package, rulat între fazele install și deploy, împachetează codul sursă















> mvn install  // va crea în /target un project-1.0-SNAPSHOT-sources.jar pe lângă project-1.0-SNAPSHOT.jar deja creat


Javadoc plugin - aproape identic cu source plugin doar că împachetează documentația Java, parte din package, are opțiuni de customizare















> mvn install   // va crea în /target un folder apidocs în care se poate explora javadoc în variantă web (index.html) + project-1.0-SNAPSHOT-javadoc.jar pe lângă project-1.0-SNAPSHOT.jar deja creat

10 noiembrie 2022

Maven class - ziua 1

Introducere

Build tool --> produce un artifact

Maven is built with Maven :)

ANT - construit ca alternativă la Make - nu este rival Maven, se pot folosi împreună


mvn versions:update-properties  - face update la toate dependințele din pom cu ultimele lor versiuni publicate


<build>

  <finalName> GEO </finalName>   <!-- app se va numi GEO.jar -->

  <plugins>

    <plugin>

          ...

    </plugin>

  </plugins>

</build>


> mvn compile --> .class files

> mvn package --> .jar files


Structura Maven

- Maven se uită prestabilit în src/main/java

- compilează in /target

- pom.xml: project info (groupId, artifactId, version, packaging (jar/war)), dependencies (same info), goals, etc

Goals

  • clean
  • compile
  • package (rulează deja compile)
  • install (ruleaza package și instalează jar/war în local repository)
  • deploy (rulează install și copiază rezultatul într-un repo remote)


Maven storage prestabilit: ~/.m2/repository


Dependencies

Dependency: specificare groupId, artifactId, version

SNAPSHOT este versiunea inițială a proiectului în dezvoltare

  - se pot folosi si sufixele M1 (milestone1) sau RC1 (release candidate1) când urmează să fie lansat

  - sufixe RELEASE sau FINAL pt proiectul final


Tipuri de packaging: pom, jar, war, ear, maven-plugin; toate sunt arhive zip la bază; tipul prestabilit este jar

Diferențe între jar, war și ear:

  • create pentru medii diferite
  • la nivel intern: ear trebuie să aibă un META-INF/application.xml , un war cere un WEB-INF/web.xml , iar un jar nu are astfel de cerințe

Pentru tipul de packaging pom: toate dependințele sunt descărcate în arhivă


Dependințe tranzitive: dependințe descărcate automat, de care depind dependințele declarate în proiect


Scope:

  • compile - prestabilit, dependința este disponibilă oriunde în aplicație, propagată în proiectele dependente (tranzitivă)
  • provided - la fel ca compile, dar dependința nu va fi inclusă în artifactul final; disponibilă doar la momentul compilării. Nu este tranzitivă
  • runtime - este nevoie de ea doar la execuție 
  • test (ex. junit)
  • system - deprecated, a nu se folosi! - pt a specifica direct un jar anume din sistem
  • import (...)