22 Ekim 2021 Cuma

Guice Multibinder Sınıfı

Giriş
Şu satırı dahil ederiz
import com.google.inject.multibindings.Multibinder;
Aynı arayüzü gerçekleştiren tüm sınıfları Set olarak alabilmemizi sağlar. List olarak @Inject edemeyiz.

Benzer yetenek Spring ile de geliyor. Ancak farklı olarak aynı arayüzü gerçekleştiren bean'leri List veya Set olarak alabiliriz.

Örnek
Şöyle yaparız. Böylece Action sınıfından kalıtan her şeyi alabiliriz.
Multibinder<Action> actionBinder = Multibinder.newSetBinder(binder(), Action.class);
actionBinder.addBinding().to(FooAction.class);
actionBinder.addBinding().to(BarAction.class);
Şöyle yaparız
@Inject
public Foo(Set<Action> actions) {
  ...
}
Örnek
Şöyle yaparız. Böylece elimizde soyut bir Module olur
public abstract class ActionModule extends AbstractModule {
  private Multibinder<Action> actionBinder;

  @Override
  protected void configure() {
    actionBinder = Multibinder.newSetBinder(binder(), Action.class);
    configureActions();
  }

  //Override this method to call {@link #bindAction}.
  protected abstract void configureActions();

  protected final LinkedBindingBuilder<Action> bindAction() {
    return actionBinder.addBinding();
  }
}
Module gerçekleştirimi için şöyle yaparız.
public final class MyStandardActionModule extends ActionModule {
  @Override
  protected void configureActions() {
    bindAction().to(FooAction.class);
    bindAction().to(BarAction.class);
    // If you need to instantiate an action through a Provider, do this.
    bindAction().toProvider(BazActionProvider.class);
    // You can also scope stuff:
    bindAction().to(MySingletonAction.class).in(Singleton.class);
  }
}



11 Ekim 2021 Pazartesi

Guice AbstractModule Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.inject.AbstractModule;
Metodların karşılığı şöyle
Guice DSL syntax         Mental model
bind(key).toInstance(value) map.put(key, () -> value) (instance binding)
bind(key).toProvider(provider) map.put(key, provider)    (provider binding)
bind(key).to(anotherKey) map.put(key, map.get(anotherKey)) (linked binding)
@Provides Foo provideFoo() {...} map.put(Key.get(Foo.class), module::provideFoo) (provider                                                            (method binding)
bind metodu
Örnek - to 
Şöyle yaparız. Burada her seferinde yeni bir DefaultCommunicatorImpl yaratılır
public class BasicModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(Communicator.class).to(DefaultCommunicatorImpl.class);
  }
}
Örnek - toInstance 
Şöyle yaparız. Burada her seferinde aynı DefaultCommunicatorImpl kullanılır
public class BasicModule extends AbstractModule {
DefaultCommunicatorImpl communicator = ...;
@Override protected void configure() { bind(Communicator.class).to(communicator);
} }
Örnek - toInstance 
Şöyle yaparız. Burada her seferinde yeni bir Communication yaratılır
public class BasicModule extends AbstractModule {
@Override protected void configure() {
bind(Communication.class).toInstance(new Communication(true)); } }
Örnek - toConstructor 
Şöyle yaparız. Burada her seferinde yeni bir Communication yaratılır ve Boolean alan constructor'ı kullanılır.
public class BasicModule extends AbstractModule {
@Override protected void configure() { bind(Boolean.class).toInstance(true); bind(Communication.class).toConstructor( Communication.class.getConstructor(Boolean.TYPE)); } }
install metodu
Ortak olan şeylerin bir AbstractModule altında toplanabilmesini sağlar.
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
@Override protected void configure() { install (new MyCommonModule(); } }

Guice Injector Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.inject.Injector;
createChildInjector metodu
Farklı konfigürasyonlar göre Injector yaratabilmeyi sağlar.

Örnek
Şöyle yaparız
class ForeverModule extends AbstractModule {
  ...
}

class TemporaryModule extends AbstractModule {
  ...
}

Injector foreverInjector = Guice.createInjector(new ForeverModule());

Injector injector = foreverInjector.createChildInjector(new TemporaryModule());
/*
 * Do stuff with the injector as you would normally. When you
 * get bored of that injector, create a replacement injector
 * as a child of the long-lived injector.
*/
getInstance metodu
Belirtilen Class'a ait bir nesne döner. Nesne Spring terminolojisiyle @Autowire edilmiştir.
Örnek
Şöyle yaparız
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);

Guice Kullanımı

Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>com.google.inject</groupId>
  <artifactId>guice</artifactId>
  <version>4.1.0</version>
</dependency>
Kullanım
1. Bir Injector yaratılır. Injector'ı yaratırken AbstractModule nesnesi veririz.
2. Injector.getInstance(Foo.class) çağrısı ile @Inject anotasyonları doldurulmuş bir Foo nesnesi elde ederiz
3. Eğer Enforce Explicit Binding seçili değilse, Guice JustInTimeBindings yapabilir. Yani AbstractModule tarafından bilinmeyen veya anotasyon ile işaretlenmemiş nesneleri de yaratabilir.

Örnek
Şöyle yaparız
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);
Injector Sınıfı
Injector Sınıfı yazısına taşıdım

AbstractModule Sınıfı
AbstractModule Sınıfı yazısına taşıdım

Singleton Kullanımı
Singleton 3 farklı şekilde yapılabilir.
1. At Class level
Örnek
Şöyle yaparız
@Singleton
class SpellCheckerImpl implements SpellChecker {
   
  @Override
  public void checkSpelling() { 
    ...
  }
}

class TextEditorModule extends AbstractModule {
@Override protected void configure() { bind(SpellChecker.class).to(SpellCheckerImpl.class); } }
2. At Configuration level
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
@Override protected void configure() { bind(SpellChecker.class).to(SpellCheckerImpl.class).in(Singleton.class); } }
3. At Method level
Örnek
Şöyle yaparız
class TextEditorModule extends AbstractModule {
   @Override
   protected void configure() {} 

   @Provides @Singleton
   public SpellChecker provideSpellChecker() {
      SpellChecker spellChecker = new SpellCheckerImpl();
      return spellChecker;
   }
}

27 Nisan 2021 Salı

@VisibleForTesting Anotasyonu

Giriş
Şu satırı dahil ederiz
import com.google.common.annotations.VisibleForTesting;
Açıklaması şöyle
... the annotation itself does not prevent production code from calling the annotated method
Örnek
Şöyle yaparız. Böylece testler farklı bir pakette olsa bile Bar sınıfına erişebilir
class Foo {
  ...
  @VisibleForTesting
  static class Bar {
  }
}

6 Nisan 2021 Salı

ServiceManager Sınıfı

Giriş
Şu satırı dahil ederiz
import com.google.common.util.concurrent.ServiceManager;
startAsync metodu
Örnek
Şöyle yaparız
public class ManagedGuavaServices implements Managed {
  @Inject
  private ServiceManager serviceManager;

  @Inject
  public ManagedGuavaServices(ServiceManager serviceManager) {
    this.serviceManager = serviceManager;
  }

  @Override
  public void start() throws Exception {
    serviceManager.startAsync();
    serviceManager.awaitHealthy(2, TimeUnit.SECONDS);
  }

  @Override
  public void stop() throws Exception {
    serviceManager.stopAsync();
    serviceManager.awaitStopped(2, TimeUnit.SECONDS);
 }
}

7 Mart 2021 Pazar

Traverser Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.common.graph.Traverser;
Traverse algoritmaları olarak şunlar kullanılabilir
breadthFirst(Iterable<? extends N> startNodes)
Iterable over the nodes reachable from any of the startNodes, in the order of a breadth-first traversal
breadthFirst(N startNode)
Iterable over the nodes reachable from startNode, in the order of a breadth-first traversal
Örnek
Şöyle yaparız
Node root = new Node("root");
MutableGraph<Node> myGraph = GraphBuilder.directed().build();
Node node1=new Node(" 1 ");
Node node2=new Node(" 2 ");
Node node3=new Node(" 3 ");
Node node4=new Node(" 4 ");
Node node5=new Node(" 5 ");
myGraph.putEdge(root, node1);
myGraph.putEdge(node1, node2);
myGraph.putEdge(node1, node3);
myGraph.putEdge(node2, node4);
myGraph.putEdge(node2, node5);
//Print the nodes Depth First
Traverser.forGraph(myGraph).breadthFirst(root)
  .forEach(x->System.out.println(x));
Çıktı olarak şunu alırız
1
3 2 5 4
depthFirstPostOrder(Iterable<? extends N> startNodes)
Iterable over the nodes reachable from any of the startNodes, in the order of a depth-first post-order traversal
Örnek
Şöyle yaparız
Node root = new Node("root");
MutableGraph<Node> myGraph = GraphBuilder.directed().build();
Node node1=new Node(" 1 ");
Node node2=new Node(" 2 ");
Node node3=new Node(" 3 ");
Node node4=new Node(" 4 ");
Node node5=new Node(" 5 ");
myGraph.putEdge(root, node1);
myGraph.putEdge(node1, node2);
myGraph.putEdge(node1, node3);
myGraph.putEdge(node2, node4);
myGraph.putEdge(node2, node5);
//Print the nodes Depth First
Traverser.forGraph(myGraph).depthFirstPostOrder(root)
  .forEach(x->System.out.println(x));
root ->(1)
1 -> (2,3)
2 -> (4,5)
Çıktı olarak şunu alırız
1
3
5
4
2
depthFirstPostOrder(N startNode) metodu
Iterable over the nodes reachable from startNode, in the order of a depth-first post-order traversal
Örnek
Şöyle yaparız
Node root = new Node("root");
Graph<Node> graph = GraphBuilder.directed()
  .nodeOrder(ElementOrder.insertion())
  .<Node>immutable()
  .putEdge(root, new Node("one"))
  .putEdge(root, new Node("two"))
  .putEdge(root, new Node("three"))
  .build();

//Print the nodes in traversal order.
Traverser.forGraph(graph).depthFirstPostOrder(root)
  .forEach(x->System.out.println(x));
depthFirstPreOrder(Iterable<? extends N> startNodes)
Iterable over the nodes reachable from any of the startNodes, in the order of a depth-first pre-order traversal
forGraph(SuccessorsFunction<N> graph)
Creates a new traverser for the given general graph.
forTree(SuccessorsFunction<N> tree)
Creates a new traverser for a directed acyclic graph that has at most one path from the start node(s) to any node reachable from the start node(s), and has no paths from any start node to any other start node, such as a tree or forest